Fork-join(分支/聚合活动)
1、JBPM4 Fork-join(分支/聚合活动)
当我们需要流程并发处理、执行的时候就需要分支、聚合。当出现fork的时候,流程实例不是仅仅进入其中一个分支,而是所有分支都会被激活,直到外界接口执行此分支才会往下走,所有的分支节点都聚合到join的时候,整个分支才会继续往下面走,否则,最先到达join分支的节点会一直等待在join那里等待其他。
- fork和join这两个节点总是成对出现的,有分叉必然有合并。
他们所起的作用为有多个任务必须全部完成才能进入到下一个任务中。也就是说fork标签中的全部transition全部完成后才能进入到join标签中的transition。 - 使用fork与单个task的不同之处其实仅在task的数目。
fork中的每个transition其实指向的是另外一个task,并且fork中transition指向的task并没有顺序之分,各个任务的地位是平等的。 - state节点的使用。
state的使用十分的简单,它是task的简化版,从其中文意思“状态”可知,它所起的作用只不过是一个状态标识。说白了就是记录状态的转变。
2、fork \ join \ state \ task 节点的使用
2.1 流程图示例
2.2 xml文件
<?xml version="1.0" encoding="UTF-8"?>
<process name="testProcess" xmlns="http://jbpm.org/4.4/jpdl">
<swimlane candidate-groups="anhui" name="anhui"/>
<start g="-6,173,72,48" name="start1">
<transition g="-22,-25" name="to test1" to="test1"/>
</start>
<end g="1129,60,82,51" name="end1"/>
<task g="91,166,102,56" name="test1" swimlane="anhui">
<transition g="-33,-21" name="to fork1" to="fork1"/>
</task>
<task g="624,140,109,52" name="test4" swimlane="anhui">
<transition g="-20,-22" name="to test5" to="test5"/>
</task>
<task g="805,140,105,52" name="test5" swimlane="anhui">
<transition g="-28,-24" name="to end" to="end"/>
</task>
<end g="981,144,48,48" name="end"/>
<fork g="229,165,48,48" name="fork1">
<transition name="to state1" to="state1" g="-56,-22"/>
<transition name="to state2" to="state2" g="-40,12"/>
</fork>
<join g="494,143,48,48" name="join1">
<transition g="-34,-22" name="to test4" to="test4"/>
</join>
<state name="state1" g="315,111,92,52">
<transition name="to join1" to="join1" g="-17,-22"/>
</state>
<state name="state2" g="320,205,92,52">
<transition name="to join1" to="join1" g="-50,-9"/>
</state>
</process>
2.3 运行过程分析
当部署好流程并创建一个流程实例后:
- 进入任务task-test1;
- test1任务执行结束之后,进入fork1,此时执行getCurrentActivity()函数执行结果显示当前任务是[state1,state2],这种情况印证了fork中的任务是没有顺序之分的;
- 当我们执行完成state1的任务后,再次执行 getCurrentActivity()函数,结果显示当前任务是[state2],并不是进入到了“合并”任务;
- 当将状态state1和状态state2全部结束后再次执行getCurrentActivity(),结果显示此时进入到了“合并”任务。
- 然后根据task顺序依次执行:
3.实现
1、任务完成执行函数:
/**任务完成*/
public void completedTask(String outboundTransName, String userID, String userName) {
Task task = findTask(userID, false);
if(task != null){
if(outboundTransName != null){
taskService.completeTask(task.getId(),outboundTransName);
}else{
taskService.completeTask(task.getId());
}
}
}
2、状态完成执行函数:
/**状态结束 */
public void executeActiveActivityByName(String activityName) {
String eid = executionService.createProcessInstanceQuery().processInstanceId(processID).uniqueResult().findActiveExecutionIn(activityName).getId();
executionService.signalExecutionById(eid);
}
3、总测试类:
/**
* 测试工作流任务
* @author rmling
*/
public class TestJbpmProcess {
public static void main(String[] args) {
CommUtil.initDataSource_name2topo();
User user = createTestUser();
long ctl_id = 111111l;
TestProcessInstance.getInstance().startUpProcess(ctl_id, user);
// test1->fork1->state1\state2->join1->test4->test5->end
try {
//test1
ProcessJobRel task = TestProcessInstance.getInstance().getActiveProcessTask(ctl_id, user);
System.out.println(" -- 当前任务:"+task.getActiveTaskName());
//fork1
System.out.println(" -- 结束任务:"+task.getActiveTaskName());
System.out.println(TestProcessInstance.getInstance().completedProcessTask(ctl_id,null,user.getId(),user.getName()));
System.out.println(" -- test1任务结束后,通过fork指向分支:"+task.getActiveTaskName());
TestProcessInstance.getInstance().findActiveActivityNames(ctl_id);
//state1\state2
System.out.println(" -- 结束任务:state1");
TestProcessInstance.getInstance().executeActiveActivityByName(ctl_id, "state1");
System.out.println(" -- state1执行结束,剩下分支:");
TestProcessInstance.getInstance().findActiveActivityNames(ctl_id);
System.out.println(" -- 结束任务:state2");
TestProcessInstance.getInstance().executeActiveActivityByName(ctl_id, "state2");
System.out.println(" -- state2执行结束,剩下分支为空");
TestProcessInstance.getInstance().findActiveActivityNames(ctl_id);
//test4
task = TestProcessInstance.getInstance().getActiveProcessTask(ctl_id, user);
System.out.println(" -- 通过join1聚合,进入任务:"+task.getActiveTaskName());
System.out.println(" -- 结束任务:"+task.getActiveTaskName());
TestProcessInstance.getInstance().completedProcessTask(ctl_id,null,user.getId(),user.getName());
//test5
task = TestProcessInstance.getInstance().getActiveProcessTask(ctl_id, user);
System.out.println(" -- 进入任务:"+task.getActiveTaskName());
System.out.println(" -- 结束任务:"+task.getActiveTaskName());
TestProcessInstance.getInstance().completedProcessTask(ctl_id,null,user.getId(),user.getName());
//end
task = TestProcessInstance.getInstance().getActiveProcessTask(ctl_id, user);
TestProcessInstance.getInstance().printTaskOutcomes(ctl_id, task.getActiveTaskId());
} catch (Exception e) {
System.err.println(e.getMessage());
}
TestProcessInstance.getInstance().closedProcess(ctl_id);
}
private static User createTestUser() {
User u = new User();
u.setId("1111");
u.setName("路飞");
u.setAreaId("340000");
return u;
}
}