应用场景:
多个部门发起资金计划,最后统一到财务部审批,每个部门发起资金计划是一个子流程,财务部审批是多个部门的计划同时审批,审批完成后,再提交上级领导审批。
流程如下:
要解决以上问题,需要实现多个子流程并行处理的功能。在Activiti5有一个比较强的节点属性就是多实例,它可以支持多实例的子流程,多实例任务,多实体脚本等。目前支持多实例的节点类型有:
多实例还有并行、串行区分。以下解释一下什么是并行与串行
并行代表同时进行,如把任务分给5个人来处理,这5个人同时会收到任务,并且可以同时处理,不受各自的影响。
串行代表工作或任务由一个人完成后,再由另一个人去处理,直至全部完成,每个任务依赖于前一个任务完成。
会签任务即可以由activiti多实例任务节点来实现,(上一博客有介绍如何开发设计会签任务)
在Activiti的定义中,生成多实例的定义很简单,只需要如下类似去生成以下标签,则可以完成多实例的声明,如下所示,我们要支持并行节点的多实例的定义
多实例人工任务
<userTask activiti:assignee="${assignee}" id="SignTask2" name="财务主管会签"> <extensionElements> <activiti:taskListener class="com.hotent.platform.service.bpm.listener.TaskSignCreateListener" event="create" /> <activiti:taskListener class="com.hotent.platform.service.bpm.listener.TaskAssignListener" event="assignment" /> <activiti:taskListener class="com.hotent.platform.service.bpm.listener.TaskCompleteListener" event="complete" /> </extensionElements> <multiInstanceLoopCharacteristics activiti:elementVariable="assignee" isSequential="false" activiti:collection="${taskUserAssignService.getSignUser(execution)}"> <completionCondition>${signComplete.isComplete(execution) } </completionCondition> </multiInstanceLoopCharacteristics> </userTask>
多实例子流程
<subProcess activiti:assignee="${assignee}" id="SubProcess1" name="部门资金计划流程"> <startEvent activiti:initiator="startUser" id="startEvent2" name="开始" /> <endEvent id="endEvent1" name="结束1" /> <userTask id="task3" name="助理填写"> <documentation /> <extensionElements> <activiti:taskListener class="com.hotent.platform.service.bpm.listener.TaskCreateListener" event="create" /> <activiti:taskListener class="com.hotent.platform.service.bpm.listener.TaskAssignListener" event="assignment" /> <activiti:taskListener class="com.hotent.platform.service.bpm.listener.TaskCompleteListener" event="complete" /> </extensionElements> </userTask> <userTask id="task4" name="部门领导审查"> <documentation /> <extensionElements> <activiti:taskListener class="com.hotent.platform.service.bpm.listener.TaskCreateListener" event="create" /> <activiti:taskListener class="com.hotent.platform.service.bpm.listener.TaskAssignListener" event="assignment" /> <activiti:taskListener class="com.hotent.platform.service.bpm.listener.TaskCompleteListener" event="complete" /> </extensionElements> </userTask> <sequenceFlow sourceRef="startEvent2" targetRef="task3" id="sequenceFlow1" name="" /> <sequenceFlow sourceRef="task3" targetRef="task4" id="sequenceFlow2" name="" /> <sequenceFlow sourceRef="task4" targetRef="endEvent1" id="sequenceFlow3" name="" /> <extensionElements> <activiti:executionListener event="start" class="com.hotent.platform.service.bpm.listener.StartEventListener" /> <activiti:executionListener event="end" class="com.hotent.platform.service.bpm.listener.EndEventListener" /> </extensionElements> <multiInstanceLoopCharacteristics activiti:elementVariable="assignee" isSequential="false" activiti:collection="${taskUserAssignService.getMultipleUser(execution)}" /> </subProcess>
所以关键的配置属性:
<multiInstanceLoopCharacteristics activiti:elementVariable="assignee" isSequential="false" activiti:collection="${taskUserAssignService.getSignUser(execution)}"> <completionCondition>${signComplete.isComplete(execution) } </completionCondition> </multiInstanceLoopCharacteristics>
我们在控制多实例的个数或人数时,是通过taskUserAssignService的getSignUser获取或getMultipleUser(execution)其集合的个数,从而决定产生多少个实体任务或子流程。
如实现子流程多实例的获取人数,则来自:
/** * 获取多实体子流程的执行用户集合 * @param execution * @return * @throws Execption */ public List<String> getMultipleUser(ActivityExecution execution) throws Exception{ String nodeId=execution.getActivity().getId(); ExecutionEntity executionEnt=(ExecutionEntity) execution; List<String> userIds=(List<String>)execution.getVariable(BpmConst.SUBPRO_MULTI_USERIDS); if(userIds!=null) return userIds; Map<String,FlowNode> nodeMap= NodeCache.getByActDefId(executionEnt.getProcessDefinitionId()); FlowNode subProcessNode=nodeMap.get(nodeId); FlowNode firstNode=subProcessNode.getSubFirstNode(); FlowNode secodeNode=firstNode.getNextFlowNodes().get(0); List<String> userList=nodeUserMapLocal.get().get(secodeNode.getNodeId()); logger.debug("userList size:" + userList.size()); execution.setVariable(BpmConst.SUBPRO_MULTI_USERIDS, userList); return userList; }
因为该方法会被调用多次,所以其实现的思路是第一次其集合是来自用户的界面选择的人员列表,第一次之后,放到流程变量中去,在后续的获取中,直接从流程变量中获取。
然后在任务的创建的监听器中,从流程变量assignee中获取当前任务的执行人。以上的实现还有一细节就是要解决如何查找到子流程中的第一个任务节点,并且把对应的任务人员授给这任务节点。
想部署及学习了解,可参考本人新的博客获得下载源代码。
http://redxun.iteye.com/blog/2406509
相关推荐
多线程支持: Java内置了对多线程的支持,允许程序同时执行多个任务。这对于开发需要高并发性能的应用程序(如服务器端应用、网络应用等)非常重要。 自动内存管理(垃圾回收): Java具有自动内存管理机制,通过...
第三步:在登陆后的界面文本框输入文本,然后发送 可以同时启动多个客户端 实现群聊。 浮动的广告 嵌套在html中 各种EJB之间的调用示例 7个目标文件 摘要:Java源码,初学实例,EJB调用实例 各种EJB之间的调用源码...
第三步:在登陆后的界面文本框输入文本,然后发送 可以同时启动多个客户端 实现群聊。 浮动的广告 嵌套在html中 各种EJB之间的调用示例 7个目标文件 摘要:Java源码,初学实例,EJB调用实例 各种EJB之间的调用源码...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...