利用fork-join新建Token来实现JBPM流程并发

以前看过一篇文章介绍JBPM流程并发的,也是通过fork节点,但是没有join节点直接拉到End节点,逻辑上可以实现,但是看起来让人感觉有点乱.当然了通过一个节点多个task也可以实现,可是流程图看起来总觉得别扭,那也就不是什么流程.言归正传,Token贯穿整个流程,一个Token可以有多个子Token,在fork和join中有多少走向,就会有多少子Token.那么我们可以不可以给Token添加子Token呢?答案是可以的,我们可以通过T构造函数Token(Token parent,String name)来创建一个子Token.问题又来了,什么时候创建token呢,通过试验在Fork节点是可以创建的,但是新建的Token会一直停留在fork节点上,需要手动Single下去.而在fork节点single的话会有异常,那就需要在fork和join之间拉一条transition,在这条transition来控制,在transition上的action创建Token,赋值对应的变量然后Single下去.下面介绍一下如何实现.

流程图
[img]http://jiajw0426.iteye.com/upload/picture/pic/24667/0b63cfc0-fb2c-31b4-87c4-401eafeeb5c3.jpg[/img]
流程定义
<?xml version="1.0" encoding="UTF-8"?>
<process-definition xmlns="" name="test">
<start-state name="开始节点">
<transition to="fork1"></transition>
</start-state>
<fork name="fork1">
<transition to="并发">
<action></action>
</transition>
<transition to="join1" name="control">
<action class="test.Controler"></action>
</transition>
</fork>
<task-node name="并发">
<task name="并发任务"></task>
<transition to="join1"></transition>
</task-node>
<join name="join1">
<transition to="结束"></transition>
</join>
<end-state name="结束"></end-state>
</process-definition>

流程的目的是,在流程开始时给流程变量departments赋值,不同部门用','隔开,可每个部门都要走'并发'那条线,有多少部门就并发几条,每一条对应一个Token,每个Token中有同名变量dept,当然对不同的部门这个值不同,这里通过ContextInstance的createVariable(name,value,token)方法来实现,处理task的时候也是通过对应的方法得到对应的值.下面是action 的handler类 test.Controler的代码,
package test;
import org.jbpm.context.exe.ContextInstance;
import org.jbpm.graph.def.ActionHandler;
import org.jbpm.graph.exe.ExecutionContext;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.graph.exe.Token;
public class Controler implements ActionHandler {
public void execute(ExecutionContext arg0) throws Exception {
ProcessInstance pi=arg0.getProcessInstance();
ContextInstance ci=pi.getContextInstance();
String deparments=(String) ci.getVariable("departments");
String[] deptArry=deparments.split(",");
Token root=pi.getRootToken();
//默认的token
Token degaultToken=root.getChild("1");
ci.createVariable("dept", deptArry[0], degaultToken);
//其他部门分别创建对应的token,并分别对变量dept赋值
for(int i=1;i<deptArry.length;i++){
Token newToken=new Token(root,deptArry[i]);
ci.createVariable("dept", deptArry[i], newToken);
newToken.signal();
}
}
}

测试结果代码为
package test;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import org.jbpm.JbpmConfiguration;
import org.jbpm.JbpmContext;
import org.jbpm.context.exe.ContextInstance;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.graph.exe.Token;
import org.jbpm.taskmgmt.exe.TaskInstance;
import org.jbpm.taskmgmt.exe.TaskMgmtInstance;
public class Test {
public static void main(String[] args) {

JbpmContext jc = JbpmConfiguration.getInstance().createJbpmContext();
ProcessDefinition pd = jc.getGraphSession()
.findLatestProcessDefinition("test");
ProcessInstance pi = pd.createProcessInstance();
System.out.println("新流程开始成功!!");
Token root = pi.getRootToken();
ContextInstance ci = pi.getContextInstance();
//把部门参数加入流程当中
ci.createVariable("departments", "dept1,dept2,dept3");
root.signal();
TaskMgmtInstance tmi = pi.getTaskMgmtInstance();
Collection c = tmi.getTaskInstances();
Iterator iter = c.iterator();
System.out.println("rootToken:" + root.getNode());
priintTokenChhilds(root);
while (iter.hasNext()) {
TaskInstance ti = (TaskInstance) iter.next();
Token token = ti.getToken();
String dept = (String) ci.getVariable("dept", token);
ti.end();
System.out.println("部门" + dept + "的task'" + ti.getName() + "'结束");
System.out.println("rootToken:" + root.getNode());
priintTokenChhilds(root);
}
jc.close();
}

public static void priintTokenChhilds(Token token) {
Map childs = token.getChildren();
Iterator it = childs.keySet().iterator();
while (it.hasNext()) {
Token child = (Token) childs.get(it.next());
System.out.println(child.getFullName() + ":" + child.getNode());
}
}
}

测试结果

新流程开始成功!!
rootToken:Fork(fork1)
/dept2:TaskNode(并发)
/dept3:TaskNode(并发)
/control:Join(join1)
/1:TaskNode(并发)
部门dept1的task'并发任务'结束
rootToken:Fork(fork1)
/dept2:TaskNode(并发)
/dept3:TaskNode(并发)
/control:Join(join1)
/1:Join(join1)
部门dept2的task'并发任务'结束
rootToken:Fork(fork1)
/dept2:Join(join1)
/dept3:TaskNode(并发)
/control:Join(join1)
/1:Join(join1)
部门dept3的task'并发任务'结束
rootToken:EndState(结束)
/dept2:Join(join1)
/dept3:Join(join1)
/control:Join(join1)
/1:Join(join1)

/1节点是流程默认的子Token,代表dept1那条线.
可见所有的Token结束之后,rootToken就到达了结束节点,这是对于在并发之前已经知道并发流程个数的实现方法,对于在流程中不知道并发的条数实现方式类似,只是control那那条控制线改成task节点来实现并发控制就可以.这是这个节点要手动结束
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值