JBPM实践之:并发子流程的实现

         关于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 <? xml version="1.0" encoding="UTF-8" ?>
 2 < process-definition   xmlns =""   name ="super1" >
 3      < start-state  name ="start-state1" >
 4          < transition  to ="task-node1" ></ transition >
 5      </ start-state >
 6
 7      < task-node  name ="task-node1"  create-tasks ="false"  signal ="last-wait" >
 8          < description >
 9             我们要利用这个TaskNode实现并发子流程,create-tasks="true"是为了可以手动控制任务实例的创建,同时创建子流程,
10             signal="last-wait"是为了实现当所有子流程均已完成,主流程才能继续运行的效果
11          </ description >
12          < task  name ="sub1" >
13              < description > 要并发的子流程之一 </ description >
14          </ task >
15          < task  name ="sub2" >
16              < description > 要并发的子流程之二 </ description >
17          </ task >
18          < event  type ="node-enter" >
19              < action  name ="NodeEnterAction"  class ="jbpmTest.bfzlc.action.NodeEnterAction" ></ action >
20          </ event >
21          < transition  to ="end-state1" ></ transition >
22      </ task-node >
23
24      < end-state  name ="end-state1" ></ end-state >
25
26      < event  type ="process-start" >
27          < script  name ="SuperProcessStart" >
28             System.out.println( &quot; 主流程启动,并设置主流程ID &quot; );
29          </ script >
30      </ event >
31      < event  type ="process-end" >
32          < script  name ="SuperProcessEnd" >
33             System.out.println( &quot; 主流程结束 &quot; );
34          </ script >
35      </ event >
36 </ process-definition >


    下面是主流程的Node-EnterAction的代码:

 1 public   class  NodeEnterAction  implements  ActionHandler  {
 2
 3    public void execute(ExecutionContext executionContext) throws Exception {
 4        //取得本节点所有的Task
 5        Set<Task> tasks = ((TaskNode)executionContext.getNode()).getTasks();
 6        
 7        TaskMgmtInstance tgmt = executionContext.getTaskMgmtInstance();
 8        
 9        for (Task task : tasks) {
10            //为每一个Task创建实例
11            TaskInstance taskInstance = tgmt.createTaskInstance(task, executionContext);
12            //业务Service
13            JbpmTestFacade jbpmTestFacade = ((JbpmTestFacade)SpringBeanUtil.getBean("jbpmTestFacade"));
14            //根据Task的名字,为每一个Task创建相应的子流程
15            ProcessInstance processInstance = jbpmTestFacade.createProcessInstance(task.getName());
16            //设置创建这个子流程的流程实例ID
17            processInstance.getContextInstance().setVariable("TaskInstanceID", taskInstance.getId());
18            //子流程开始流转
19            processInstance.signal();
20        }

21        
22    }

23}


        再看其中一个子流程的定义:

 1 <? xml version="1.0" encoding="UTF-8" ?>
 2 < process-definition   xmlns =""   name ="sub1" >
 3      < start-state  name ="start-state1" >
 4          < transition  to ="Sub1Task" ></ transition >
 5      </ start-state >
 6
 7      < task-node  name ="Sub1Task" >
 8          < task  name ="SubTask1" ></ task >
 9          < transition  to ="end-state1" ></ transition >
10      </ task-node >
11
12      < end-state  name ="end-state1" ></ end-state >
13
14      < event  type ="process-start" >
15          < script  name ="ProcessStartScript" >
16             System.out.println( &quot; -------------------sub1流程启动------------------------------ &quot; );
17          </ script >
18      </ event >
19
20      < event  type ="process-end" >
21          < action  name ="SubProcessEndAction"  class ="jbpmTest.bfzlc.action.SubProcessEndAction" ></ action >
22      </ event >
23 </ process-definition >
24


        下面是该子流程的ProcessEndAction:

 1 public   class  SubProcessEndAction  implements  ActionHandler  {
 2
 3    public void execute(ExecutionContext executionContext) throws Exception {
 4        System.out.println(executionContext.getProcessDefinition().getName()+"结束");
 5        //得到创建当前子流程的那个TaskInstanceID
 6        String taskInstanceID = executionContext.getContextInstance().getVariable("TaskInstanceID").toString();
 7        
 8        //业务Service
 9        JbpmTestFacade jbpmTestFacade = ((JbpmTestFacade)SpringBeanUtil.getBean("jbpmTestFacade"));
10        //取得创建当前子流程的那个主流程taskInstance
11        TaskInstance taskInstance = jbpmTestFacade.geTaskInstance(Long.valueOf(taskInstanceID));
12        taskInstance.end();
13    }

14
15}

   
     思路很清楚,代码也很简单,按照这种方式我们可以让子流程实现所有Task能实现的功能。

    文章原创,转载请注明出处!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值