一、spring的配置文件applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns=" http://www.springframework.org/schema/beans "
xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance "
xmlns:context=" http://www.springframework.org/schema/context "
xmlns:aop=" http://www.springframework.org/schema/aop "
xmlns:tx=" http://www.springframework.org/schema/tx "
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd ">
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"/>
<property name="user" value="root"/>
<property name="password" value="cqsztt"/>
<property name="initialPoolSize" value="3" />
<property name="minPoolSize" value="3" />
<property name="maxPoolSize" value="50" />
<property name="maxIdleTime" value="600" />
<property name="maxStatements" value="100" />
<property name="acquireIncrement" value="3" />
</bean>
<!--spring的配置文件有两处需要改动的地方,此为1:
springHelper实现了ApplicationContextAware接口,springHelper可以从spring容器中获得ApplicationContext,
然后springHelper可以利用ApplicationContext和jbpm.cfg.xml(jbpm的配置文件)一起生成伟大的processEngine。
配置到这一步的时候,有些人就开始着急测试,多次碰壁后,有的高手居然想到了使用Spring 的IOC功能自己写个processEngin工厂
,大家都知道jbpm使用了hibernate,但如何将hibernate的sessionFactory注入给JBPM呢?莫及,继续往下看
-->
<bean id="springHelper" class="org.jbpm.pvm.internal.processengine.SpringHelper" />
<bean id="processEngine" factory-bean="springHelper" factory-method="createProcessEngine" />
<!--Hibernate SessionFatory-->
<bean id="sessionFactory"
class="com.travelsky.bravo.core.utils.AutoLoadSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mappingResources">
<list>
<!--此处为第二处需要修改的地方
此处千万不要忘记了 ,这5个映射关系会在spring容器初始化的时候persistent到数据库中,如果没有,肯定会报exception
写到这里我要说明下:看过jbpm有个关于hibernate配置的文件:jbpm.hibernate.cfg.xml,我这种写法就是要去掉这个文件,
将spring + jbmp都使用一个Hibernate的配置,也就不会出现两个sessionFactory和两个database的情况了。有的同学可 发表不同的意见认为:将hibernate的配置信息写到一个单独的文件里,感觉清爽些。但是,无论如何,你总得在这个文件里配置 sessionFactory吧,所以总得配置hibernate的东东,所以干脆写在一起,将来修改起来也方便,不需要打开两个文件,至于其他细节东西 我就不到啰嗦了,到此,spring的配置文件就结束了。
-->
<value>jbpm.repository.hbm.xml</value>
<value>jbpm.execution.hbm.xml</value>
<value>jbpm.history.hbm.xml</value>
<value>jbpm.task.hbm.xml</value>
<value>jbpm.identity.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.Oracle10gDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!--事务管理的配置,不这么配置不影响ssh+jbpm整合-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save" propagation="REQUIRED"/>
<tx:method name="update" propagation="REQUIRED"/>
<tx:method name="is*" read-only="true"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(public * com.cqs.service.impl.*.*(..))" id="userServicePointcut"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="userServicePointcut"/>
</aop:config>
<!--不影响ssh+jbpm整合-->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
</beans>
二、 jbpm的配置文件
1、jbpm.cfg.xml
< jbpm-configuration >
< import resource =" jbpm.default.cfg.xml " />
< import resource =" jbpm.tx.spring.cfg.xml " /><!--jbpm.tx.hibernate.cfg.xml不用了,无需其他配置-->
< import resource =" jbpm.jpdl.cfg.xml " />
< import resource =" jbpm.bpmn.cfg.xml " />
< import resource =" jbpm.identity.cfg.xml " />
< import resource =" jbpm.businesscalendar.cfg.xml " />
</ jbpm-configuration >
三、 部署到Tomcat
整合struts2就没什么好讲的了,主要是spring和struts2整合,jbpm部署到tomcat6的时候,主要jar包冲突的问 题,tomcat的lib里面的东西和项目lib里面的jar包版本等不一样的时候容易造成load到内存中的字节码出现乱七八糟的问题。
需要特别说明的是
1、WEB-INF/lib下面的三个jar包juel.jar,juel-engine.jar,juel-impl.jar剪切 到tomcat的lib下
2、在tomcat的lib中新加javaee.jar,重新部署,并启动tomcat,如果成功即可,不成功需要删除tomcat lib下的el-api.jar
3、有人数tomcat5下不会出现jar包冲突的情况,我不知道,没用过,我就不试了,哈哈
ProcessEngine processEngine = Configuration.getProcessEngine(); RepositoryService repositoryService = processEngine.getRepositoryService(); //repositoryService.createDeployment().addResourceFromClasspath("leave.jpdl.xml").deploy(); ZipInputStream zis = new ZipInputStream(this.getClass().getResourceAsStream("/doc.zip")); repositoryService.createDeployment().addResourcesFromZipInputStream(zis).deploy();将jPDL的图片发布到jBPM中,页面上的代码示例如下:
<%! public InputStream showWebPicture(){ ProcessEngine engine = Configuration.getProcessEngine(); RepositoryService rs = engine.getRepositoryService(); ProcessDefinition pd = rs.createProcessDefinitionQuery().processDefinitionId("at-4").uniqueResult(); InputStream in = rs.getResourceAsStream(pd.getDeploymentId(), "at.png"); return in; } %><% InputStream in = showWebPicture(); byte bs[] = new byte[1024]; while(in.read(bs)!=-1){ response.getOutputStream().write(bs); } out.clear(); out = pageContext.pushBody(); %>
ProcessInstance pi = executionService.findProcessInstanceById("test1.10001"); Set<String> activityNames = pi.findActiveActivityNames(); for (String activityName:activityNames){ String pdId = pi.getProcessDefinitionId(); ActivityCoordinates ac = repositoryService.getActivityCoordinates(pdId,activityName); System.out.println("activityName="+activityName); System.out.println("x="+ac.getX()); System.out.println("y="+ac.getY()); System.out.println("height="+ac.getHeight()); System.out.println("width="+ac.getWidth()); System.out.println("---------------------"); }
<% ProcessInstance pi = executionService.findProcessInstanceById("test1.10001"); Set<String> activityNames = pi.findActiveActivityNames(); for (String acitiveAcitityName:activityNames){ String pdId = pi.getProcessDefinitionId(); ActivityCoordinates ac = repositoryService.getActivityCoordinates(pdId,acitiveAcitityName); %> <div style="position:absolute;border:1px solid red; left:<%=ac.getX()%>px;top:<%=ac.getY()%>px; width:<%=ac.getWidth()%>px;height:<%=ac.getHeight()%>px;"> </div> <%}%>
ProcessInstance pi = executionService.findProcessInstanceById("test1.10001"); Set<String> activityNames = pi.findActiveActivityNames(); for (String acitiveAcitityName:activityNames){ String pdId = pi.getProcessDefinitionId(); ActivityCoordinates ac = repositoryService.getActivityCoordinates(pdId,acitiveAcitityName); %> <div style="position:absolute;border:1px solid red; left:<%=ac.getX()%>px;top:<%=ac.getY()%>px; width:<%=ac.getWidth()%>px;height:<%=ac.getHeight()%>px;"> </div> <%}%>
TaskImpl mainTask = session.createTask(); mainTask.setAssignee(null); mainTask.setName("HQ"); mainTask.setActivityName(aexe.getActivityName()); mainTask.setExecution(exe); mainTask.setExecutionDbid(exe.getDbid()); mainTask.setSignalling(false);
String users = (String) exe.getVariable("hqrs"); List<String> hqUsers = new ArrayList<String>(); for(String user : users.split(",")){ hqUsers.add(user); TaskImpl subTask = mainTask.createSubTask(); subTask.setActivityName(aexe.getActivityName()); subTask.setAssignee(user); //子对象不应该有execution对象,它使用父task的execution对象 // subTask.setExecution(exe); subTask.setName(mainTask.getName()+"_"+user); subTask.setSignalling(false); subTask.setExecutionDbid(exe.getDbid()); session.save(subTask); HistoryEvent.fire(new TaskActivityStart(subTask),exe); }
public void signal(ActivityExecution aexe, String outComingName, Map<String, ?> params)throws Exception { ProcessEngine engine = Configuration.getProcessEngine(); ExecutionImpl exe =(ExecutionImpl)aexe; TaskService ts = engine.getTaskService();//1:判断这个人是否应该参与会签
List hqUsers= (List<String>) exe.getVariable("hqUsers"); String user = (String)params.get("oper"); if(!hqUsers.contains(user)){ //继续等待 System.out.println("你不能参与会签"); exe.waitForSignal(); return; }
Task mainTask = ts.createTaskQuery().processInstanceId(exe.getProcessInstance() .getId()).activityName("custom1").uniqueResult(); //2.2找到所有的子task List<Task> subTaskList = ts.getSubTasks(mainTask.getId()); boolean hasHQ = true; for(Task t : subTaskList){
hasHQ = false; ts.completeTask(t.getId()); break; } }//2.3如果是以前会签过的,就停止
if(hasHQ){ System.out.println("你已经会签过了"); //继续等待 exe.waitForSignal(); return; }
Map<String,String> results = new HashMap<String,String>(); Object tempObject = exe.getVariable("results"); if(tempObject!=null){ results = (Map<String,String>)tempObject; } results.put(user, ""+params.get("result")); exe.setVariable("results", results);//5:然后根据业务规则进行判断,看是否满足会签结束的条件
int ok = 0; int no = 0; for(String s : results.values()){ if("yes".equals(s)){ ok++; }else if("no".equals(s)){ no++; } } if(ok > hqUsers.size()/2){ //说明ok了,转到toT2
exe.take(t); }else if(no > hqUsers.size()/2){ //说明no了,转到toT3 overTasks(exe); Transition t = exe.getActivity().getOutgoingTransition("toT3"); exe.take(t); }else{//7:如果不满足,那么就继续等待
exe.waitForSignal(); } } private void overTasks(ExecutionImpl exe){ ProcessEngine engine = Configuration.getProcessEngine(); TaskService ts = engine.getTaskService(); Task mainTask = ts.createTaskQuery().processInstanceId( exe.getProcessInstance().getId()) .activityName("custom1").uniqueResult();//2.2找到所有的子task,然后终止掉
List<Task> subTaskList = ts.getSubTasks(mainTask.getId()); for(Task t : subTaskList){ ts.completeTask(t.getId()); }