技术交流28群

服务热线

135-6963-3175

微信服务号

activiti之内嵌子流程\事件子流程\调用子流程\特殊子流程区别 更新时间 2022-3-23 浏览4260次

内嵌子流程和调用子流程、事件子流程有什么区别?

BPMN 2.0 将subProcess(通常也称为嵌入式子流程)和看起来非常相似的callActivity区分开来。从概念的角度来看,当流程执行到达活动时,两者都会调用子流程

     不同之处在于callActivity引用了流程定义外部的流程,而子流程嵌入在原始流程定义中callActivity的主要用例是拥有一个可重用的流程定义,可以从多个其他流程定义中调用。

     subProcess:

            1.一个子流程只能有一个无启动事件,不允许有其他启动事件类型。一个子流程必须至少有一个结束事件。请注意,BPMN 2.0 规范允许在子流程中省略开始和结束事件,但当前的 Activiti 实现不支持这一点。

            2.序列流不能跨越子流程边界。        


callActivity

      当流程执行到达callActivity时,会创建一个新的execution,它是到达callActivity的execution的child execution。这个child execution用于执行子流程,像在常规流程中一样创建并行child execution。super execution等待子流程完全结束,然后继续原来的进程。

callActivity例子:

<startEvent id="theStart" />
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="receiveOrder" />

<manualTask id="receiveOrder" name="Receive Order" />
<sequenceFlow id="flow2" sourceRef="receiveOrder" targetRef="callCheckCreditProcess" />

<callActivity id="callSubProcess" calledElement="checkCreditProcess" activiti:businessKey="${myVariable}"
activiti:inheritBusinessKey="true">
  <extensionElements>
  <activiti:in source="someVariableInMainProcess" target="nameOfVariableInSubProcess" />
  <activiti:out source="someVariableInSubProcess" target="nameOfVariableInMainProcess" />
  </extensionElements>
</callActivity>

<sequenceFlow id="flow3" sourceRef="callCheckCreditProcess" targetRef="prepareAndShipTask" />

<userTask id="prepareAndShipTask" name="Prepare and Ship" />
<sequenceFlow id="flow4" sourceRef="prepareAndShipTask" targetRef="end" />

<endEvent id="end" />

businessKey属性可用于在子流程实例上设置自定义业务键值。

使用 true 值定义inheritBusinessKey属性会将子流程上的业务键值设置为调用流程中定义的业务键值。

可以将流程变量传递给子流程,反之亦然。数据在启动时复制到子进程中,并在结束时复制回主进程中。

上面callActivity调用了id为checkCreditProcess的流程定义

<bpmn2:process id="checkCreditProcess" tns:packageName="net.hs.cw.bpme.ta" name="InputNav" isExecutable="true" processType="Private">
      <bpmn2:startEvent id="StartEvent_1" name="StartProcess">
        <bpmn2:extensionElements>
          <tns:metaData name="elementname">
            <tns:metaValue><![CDATA[StartProcess]]></tns:metaValue>
          </tns:metaData>
        </bpmn2:extensionElements>
      <bpmn2:outgoing>SequenceFlow_1</bpmn2:outgoing>
     </bpmn2:startEvent>
      ......
</bpmn2:process>

activiti中内嵌子流程(call activity)是新启动一个流程,该子流程和父流程没有父子关系。该子流程的proc_inst_id_的parent_id_是空的。
如果想要获取父流程的proc_inst_id_,可以通过执行环境(id_)和父执行环境(super_exec_)来获取。上述字段都是act_ru_execution表中。

事件子流程

      事件子流程是 BPMN 2.0 中的新功能。事件子流程是由事件触发的子流程。可以在流程级别或任何子流程级别添加事件子流程。用于触发事件子流程的事件是使用启动事件配置的。由此可见,事件子流程不支持任何启动事件。可以使用消息事件、错误事件、信号事件、计时器事件或补偿事件等事件来触发事件子流程。当创建托管事件子流程的范围(流程实例或子流程)时,将创建对启动事件的订阅。当作用域被销毁时,订阅被删除。

      事件子流程可能是中断的或非中断的。中断子进程会取消当前范围内的所有执行。一个不中断的事件子流程产生一个新的并发执行。虽然对于托管它的范围的每次激活只能触发一次中断事件子流程,但可以多次触发非中断事件子流程。子流程是否中断的事实是使用触发事件子流程的启动事件来配置的。

      事件子流程不得有任何传入或传出的序列流。由于事件子流程是由事件触发的,因此传入的序列流没有意义。当一个事件子流程结束时,要么结束当前范围(在中断事件子流程的情况下),要么结束为非中断子流程产生的并发执行。

当前限制:

      Activiti 只支持中断事件子流程。

      Activiti 仅支持使用错误启动事件或消息启动事件触发的事件子流程。

事件子流程位于“流程级别”,即范围为流程实例。

例子:

<subProcess id="eventSubProcess" triggeredByEvent="true">
<startEvent id="catchError">
<errorEventDefinition errorRef="error" />
</startEvent>
<sequenceFlow id="flow2" sourceRef="catchError" targetRef="taskAfterErrorCatch" />
<userTask id="taskAfterErrorCatch" name="Provide additional data" />
</subProcess>

triggeredByEvent必须具有值true


特殊子流程

主要字段

public class AdhocSubProcess extends SubProcess {
  public static final String ORDERING_PARALLEL = "Parallel";
  public static final String ORDERING_SEQUENTIALL = "Sequential";
  
  protected String completionCondition;//完成条件
  protected String ordering = ORDERING_PARALLEL;//串行
  protected boolean cancelRemainingInstances = true;//取消剩余实例

xml:

<process id="simpleSubProcess">
    <startEvent id="theStart" />
    <sequenceFlow id="flow1" sourceRef="theStart" targetRef="adhocSubProcess" />
    
    <adHocSubProcess id="adhocSubProcess" ordering="Sequential">
      
      <userTask id="subProcessTask" name="Task in subprocess" />
      <userTask id="subProcessTask2" name="Task2 in subprocess" />
      
      <completionCondition>${completed}</completionCondition>
    
    </adHocSubProcess>
    <sequenceFlow id="flow2" sourceRef="adhocSubProcess" targetRef="afterTask" />
    
    <userTask id="afterTask" name="After task" />
    
    <sequenceFlow id="flow3" sourceRef="afterTask" targetRef="theEnd" />
    
    <endEvent id="theEnd" />
    
  </process>

有一个完成条件,会在出线的时候(TakeOutgoingSequenceFlowsOperation)判断是否满足完成条件,若满足则结束特殊子流程。

在特别子流程的容器中可以存放多个流程节点,该类型的子流程无需再子流程中为节点配置任何的出线,这些节点在运行前不存在流程顺序,流程的顺序和执行,由执行时决定。