JBPM4提供了sub-process活动,即子流程活动,这样就允许您在“主流程”定义中调用其它的流程定义,从而“组装”您的流程定义。在运行到子流程活动时,工作流引擎将创建一个子流程实例,然后等待直到其流转完成,当子流程实例流转完成后,流程就会回到“主流程”并流向下一步。
sub-process活动的几个重要属性:
sub-process-id: 流程定义的ID标识,可以通过一个流程的ID去引用此流程定义的指定版本
sub-process-key: 流程的key标识,通过key去引用该流程定义的最新版本,该流程定义的最新版本会在每次活动实例执行时计算得出。sub-process-id与sub-process-key必选其一。
outcome: 当sub-process活动的transition元素具有outcome-value时必须要有此属性。该属性为当子流程执行结束时执行的一表达式,表达式值用来匹配流出转移(transition)的名称或流出转移中的outcome-value元素值,起到选择sub-process活动下一步走向的作用。
parameter-in: 子流程输入参数,即声明一个变量,在创建子流程实例时传入。
parameter-out: 子流程输出参数,即声明一个变量,在子流程实例结束时,返回给父流程实例。
具体解释一下parameter-in元素的属性:
subvar: 这是必须要有的,指定被赋值的子流程变量的名称。
var: 从父流程环境中输入的变量名称。
expr: 此表达式在父流程环境中解析,结果值会被输入到对应的子流程变量中,var和expr二者必须指定一个。
parameter-out元素属性与parameter-in相似。
sub-process活动中transition中的outcome-value元素:outcome-value是一个值表达式。子流程活动结束时,如果某transition的outcome-value值与子流程的outcome值匹配,那么,父流程的下一步将会通过此transition。
例如:
<?xml version="1.0" encoding="UTF-8"?> <process name="subProcessTest" xmlns="http://jbpm.org/4.4/jpdl"> <start g="40,127,48,48" name="start1"> <transition to="review"/> </start> <sub-process g="220,128,120,52" name="review" sub-process-key="subProcessReview" outcome="#{result}"> <transition g="-44,-22" name="notok" to="update"/> <transition g="278,275:-51,-22" name="reject" to="close"/> <transition g="274,47:-31,-12" name="ok" to="next step"> <outcome-value> <int value="100"/> </outcome-value> </transition> </sub-process> <state g="506,132,92,52" name="update"> <transition to="end1"/> </state> <end g="744,132,48,48" name="end1"/> <state g="507,247,92,52" name="close"> <transition to="end1"/> </state> <state g="505,24,92,52" name="next step"> <transition to="end1"/> </state> </process>
这里,如果说子流程返回的流程变量result的值为100的话,那么当子流程流转结束后主流程将通过名称为ok的transition流出,当然,如果说result流程变量的值为reject的话话主流程就将通过名称为reject的transtion流出了。
用法一:通过sub-process活动的outcome属性值去影响父流程的流出转移,如上所说。
用法二:通过设置子流程不同的end活动名称自动关联父流程的流出转移,如下:
父流程的流程定义文件内容:
<?xml version="1.0" encoding="UTF-8"?> <process name="subProcessTest" xmlns="http://jbpm.org/4.4/jpdl"> <start g="40,127,48,48" name="start1"> <transition to="review"/> </start> <sub-process g="220,128,120,52" name="review" sub-process-key="subProcessReview"> <transition g="-44,-22" name="notok" to="update"/> <transition g="278,275:-51,-22" name="reject" to="close"/> <transition g="274,47:-31,-12" name="ok" to="next step"/> </sub-process> <state g="506,132,92,52" name="update"> <transition to="end1"/> </state> <end g="744,132,48,48" name="end1"/> <state g="507,247,92,52" name="close"> <transition to="end1"/> </state> <state g="505,24,92,52" name="next step"> <transition to="end1"/> </state> </process>
大家可以看到,sub-process活动已经没有了outcome属性
子流程的流程定义文件内容:
<?xml version="1.0" encoding="UTF-8"?> <process name="subProcessReview" xmlns="http://jbpm.org/4.4/jpdl"> <start g="122,139,48,48" name="start1"> <transition g="-70,-22" name="to approve" to="approve"/> </start> <task assignee="zhangsan" g="339,140,92,52" name="approve"> <transition name="to ok" to="ok" g="-36,-22"/> <transition name="to notok" to="notok" g="-55,-22"/> <transition name="to reject" to="reject" g="-53,-22"/> </task> <end g="595,144,48,48" name="notok"/> <end name="ok" g="595,44,48,48"/> <end name="reject" g="599,274,48,48"/> </process>
大家可以看到,三个end活动的名称刚好与主流程的三个transition的名称相对应,在子流程中提交任务后,子流程执行就会结束,如果提交任务走的是名称为ok的end活动,那么主流程就将通过名称为ok的transition流出,其它的也是如此。
这种方法比使用outcome属性更容易理解:一个流程可以定义多个end活动,那么子流程可以定义多个不同名称的end活动,这些end活动的名称自动与父流程的流出转移名称做同名关联,名称相匹配则通过。