BPMN2.0区分一般的子流程,通常也称作嵌入式子流程,与调用活动,尽管他们看起来很像。从概念上说,两者都在流程执行到达该活动时,调用一个子流程。区别在于:调用活动引用一个流程定义外部的流程,而subprocess嵌入在原有流程定义内。调用活动的主要使用场景,是它有一个可重复使用的流程定义,可以在多个其他流程定义中调用。
当流程执行到大call activity时,会创建一个新的执行,作为达到调用活动的执行的子执行。这个子执行之后用于执行子流程,潜在地创建了类似普通流程的并行子执行。父执行将等待子流程完成,之后沿原流程继续执行。
调用活动是一个普通活动,需要有通过key引用流程定义的calledElement。在实际使用中,这通常意味着在calledElement中使用流程的id。
下面我们通过一个demo来验证调用子流程的执行过程:
1、首先创建两个流程:主流程master、子流程sub,主流程调用子流程(调用节点called Element填写子流程的id)
<process id="myProcess" isClosed="false" isExecutable="true" processType="None">
<startEvent id="start" name="开始"/>
<userTask activiti:exclusive="true" id="commit" name="提交"/>
<callActivity activiti:exclusive="true" calledElement="subProcess" id="callsub" name="调用子流程"/>
<userTask activiti:exclusive="true" id="check" name="审核"/>
<endEvent id="end" name="结束"/>
<sequenceFlow id="_7" sourceRef="commit" targetRef="callsub"/>
<sequenceFlow id="_8" sourceRef="callsub" targetRef="check"/>
<sequenceFlow id="_9" sourceRef="check" targetRef="end"/>
<sequenceFlow id="_10" sourceRef="start" targetRef="commit"/>
</process>
2、部署主流程、子流程后,启动主流程查看流程实例表、流程执行表、当前任务表
3、提交当前任务,再次查看这3张表
可以看到,主流程走到调用节点,自动启动子流程,为其创建一个执行流。
4、子流程结束后,再次查看这3张表
可以看到子流程实例结束,回到主流程继续执行。
调用子流程传递参数
由于调用式的子流程是独立定义在一个流程文件中的,因此当执行流到达调用式子流程时,会创建新的流程实例。RuntimeService的setVariable等方法设置流程参数,这些流程参数的作用域只限于所设置的执行流,对于调用式子流程这种会产生新的流程实例的“特殊情况”,就需要使用另外的方式解决。Activiti提供了扩展配置,允许流程参数在主流程和子流程中传递。这块我暂时还没有尝试,后期尝试验证下再补充上。