jBPM4工作流引擎 网络知识点整理汇总 WEB整合spring2.5+hibernate开发及典型业务
<beans xmlns="
??? <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" />
<bean id="processEngine" factory-bean="springHelper" factory-method="createProcessEngine" />
<!--Hibernate SessionFatory-->
<bean id="sessionFactory"
?? 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></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" ref="sessionFactory"></property>
</bean>
</beans>
二、 jbpm的配置文件
1、jbpm.cfg.xml< import resource =" jbpm.jpdl.cfg.xml " />
</ jbpm-configuration >
三、 部署到TomcatProcessEngine 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(); ?<%!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);}?//把应该参与会签的人员保存下来,后面好用到 exe.setVariable("hqUsers", hqUsers); 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;}?//2:判断这个人是否会签过了 //2.1先找到主task
Task mainTask = ts.createTaskQuery().processInstanceId(exe.getProcessInstance().getId()).activityName("custom1").uniqueResult();//2.2找到所有的子taskList<Task> subTaskList = ts.getSubTasks(mainTask.getId());boolean hasHQ = true;for(Task t : subTaskList){?//2.3判断这个人是否会签过了 if(user.equals(t.getAssignee())){ //存在就表示还没有会签,就把这个任务终止了
hasHQ = false;ts.completeTask(t.getId());break;}}?//2.3如果是以前会签过的,就停止
if(hasHQ){System.out.println("你已经会签过了");//继续等待exe.waitForSignal();return;}?//3:如果都没有,把这个人的任务结束了,上面已经做了 //4:把这个人的会签结果保存下来
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?//6:如果满足 //6.1先结束其他还没有完成会签的任务 //6.2结束会签主任伍 overTasks(exe); //6.3判断应该走哪一条转移 Transition t = exe.getActivity().getOutgoingTransition("toT2"); //6.4获取转移,然后接收它,从而实现流转
exe.take(t);}else if(no > hqUsers.size()/2){//说明no了,转到toT3overTasks(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());}?//2.3终止主task //2.1先恢复HistoryActivityInstanceDbid exe.setHistoryActivityInstanceDbid( (Long) exe.getVariable("historyAi")); ts.completeTask(mainTask.getId()); } 委派介绍 委派,又称代理,是一种很常见的任务再分配机制。 比如,公司所有的个人公积金业务都需要文书小王来处理;但是,如果小王出差了呢?难道要等他回来再处理么?这时候就需要把任务委派给别人。 ? 委派的实现 在jPDL里也没有委派这种活动,同样需要由我们自己来实现。 一个很好的思路就是:实现AssignmentHandler接口,在assign方法的实现里面,通过检索数据库,查看每个人的onDuty字段,来判断该工作人员是否在工作状态;如果不再工作状态,那么就去委派表里面检索指定的相应的委派人员,然后将任务分配给他即可。