关于JBPM中并发子流程的实现方式,网上有很多的说法,但是好像每种办法都有这样那样的缺点,要么实现太复杂,要么就是会使Token无法继续流转。这里我介绍一种我的并发子流程的实现方式:使用TaskNode使任务并行的方式,模拟实现JBPM子流程的并发执行。
我先简单的介绍一下实现思路:
1、数据库中应该有至少三个已经发布过的流程定义(ProcessDefinition),发布的顺序无所谓,一个主流程两个子流程
2、我们在主流程中要实现并发子流程的环节放置TaskNode,设置create-tasks="false"、signal="last-wait"
3、我们想要实现几个子流程的并发就在第二步放置的TaskNode中放置几个Task,每个Task的名字都是要并发的子流程的名称
4、在TaskNode的Node-Enter action中,我们手动为每一个Task创建一个任务实例,同时我们取得Task的名字也就是要并发的子流程的名字,创建流程实例
5、为每个新创建的流程实例设置流程变量:TaskInstanceID表示创建当前子流程的那个主流程任务实例ID,并使子流程开始流转
6、子流程结束,取得流程变量TaskInstanceID,该流程变量TaskInstanceID是创建他的那个主流程的任务实例,得到该TaskInstance,并TaskInstance.end();
这个时候因为我们设置了TaskNode的Signal为"last-wait",所以当所有的子流程均结束的时候,主流程才会继续,这样我们也就实现了子流程的并发效果。很简单的一个思路实现起来也并不复杂.
首先让我们看一下主流程的流程定义:
1
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
<?xml version="1.0" encoding="UTF-8"?>
2
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
<process-definition xmlns="" name="super1">
3
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
<start-state name="start-state1">
4
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
<transition to="task-node1"></transition>
5
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
</start-state>
6
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
7
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
<task-node name="task-node1" create-tasks="false" signal="last-wait">
8
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
<description>
9
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
我们要利用这个TaskNode实现并发子流程,create-tasks="true"是为了可以手动控制任务实例的创建,同时创建子流程,
10
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
signal="last-wait"是为了实现当所有子流程均已完成,主流程才能继续运行的效果
11
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
</description>
12
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
<task name="sub1">
13
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
<description>要并发的子流程之一</description>
14
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
</task>
15
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
<task name="sub2">
16
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
<description>要并发的子流程之二</description>
17
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
18
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
<event type="node-enter">
19
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
<action name="NodeEnterAction" class="jbpmTest.bfzlc.action.NodeEnterAction"></action>
20
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
</event>
21
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
<transition to="end-state1"></transition>
22
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
</task-node>
23
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
24
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
<end-state name="end-state1"></end-state>
25
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
26
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
<event type="process-start">
27
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
<script name="SuperProcessStart">
28
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
System.out.println("主流程启动,并设置主流程ID");
29
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
</script>
30
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
</event>
31
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
<event type="process-end">
32
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
<script name="SuperProcessEnd">
33
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
System.out.println("主流程结束");
34
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
35
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
36
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
</process-definition>
下面是主流程的Node-EnterAction的代码:
public class NodeEnterAction implements ActionHandler
{
public void execute(ExecutionContext executionContext) throws Exception
//取得本节点所有的Task
Set<Task> tasks = ((TaskNode)executionContext.getNode()).getTasks();
TaskMgmtInstance tgmt = executionContext.getTaskMgmtInstance();
for (Task task : tasks)
//为每一个Task创建实例
TaskInstance taskInstance = tgmt.createTaskInstance(task, executionContext);
//业务Service
JbpmTestFacade jbpmTestFacade = ((JbpmTestFacade)SpringBeanUtil.getBean("jbpmTestFacade"));
//根据Task的名字,为每一个Task创建相应的子流程
ProcessInstance processInstance = jbpmTestFacade.createProcessInstance(task.getName());
//设置创建这个子流程的流程实例ID
processInstance.getContextInstance().setVariable("TaskInstanceID", taskInstance.getId());
//子流程开始流转
processInstance.signal();
}
}
}
再看其中一个子流程的定义:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
<process-definition xmlns="" name="sub1">
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
<transition to="Sub1Task"></transition>
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
<task-node name="Sub1Task">
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
<task name="SubTask1"></task>
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
<script name="ProcessStartScript">
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
System.out.println("-------------------sub1流程启动------------------------------");
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
<action name="SubProcessEndAction" class="jbpmTest.bfzlc.action.SubProcessEndAction"></action>
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLl52bO9CXzJ3b0F2YpRmbJdmbp5WasRXdP9CXzV2Zh1WSvwFdl5mLhZXYqd2bsJmL3d3dvw1LcpDc0RHaiojIsJye.gif)
下面是该子流程的ProcessEndAction:
public class SubProcessEndAction implements ActionHandler
System.out.println(executionContext.getProcessDefinition().getName()+"结束
");
//得到创建当前子流程的那个TaskInstanceID
String taskInstanceID = executionContext.getContextInstance().getVariable("TaskInstanceID").toString();
//业务Service
JbpmTestFacade jbpmTestFacade = ((JbpmTestFacade)SpringBeanUtil.getBean("jbpmTestFacade"));
//取得创建当前子流程的那个主流程taskInstance
TaskInstance taskInstance = jbpmTestFacade.geTaskInstance(Long.valueOf(taskInstanceID));
taskInstance.end();
思路很清楚,代码也很简单,按照这种方式我们可以让子流程实现所有Task能实现的功能。
文章原创,转载请注明出处:http://www.blogjava.net/ycyk168/archive/2008/11/12/240096.html