Activiti6.0(十二)子流程

目录

一、概述

二、子流程

1、嵌入子流程

2、调用子流程

3、事件子流程

三、总结


一、概述

子流程是包含其他的活动、网关、事件等的活动,其本身构成一个流程,并作为更大流程的一部分,子流程完全在父流程中定义(这就是为什么经常被称作嵌入式子流程),子流程也是实际业务场景中比较常见的一个需求。

Activiti提供了三种子流程的实现,分别是 嵌入子流程、调用子流程、事件子流程,下面分别介绍。

二、子流程

1、嵌入子流程

对应Activiti-app中的

所谓嵌入子流程,即子流程元素<subProcess>内嵌在主流程元素<process>之内,只能在该主流程中使用,外部流程无法调用。这种子流程一般作为局部通用逻辑处理或为特定业务需求服务,会使得主流程看起来比较直观。流程图看如下:

xml为:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef">
  <process id="mainProcess" name="主流程" isExecutable="true">
    <startEvent id="startEvent1"></startEvent>
    <userTask id="sid-4C9AE06D-43FA-4325-80D5-038F495B46EE" name="子流程前" activiti:assignee="test">
      <extensionElements>
        <modeler:activiti-idm-assignee xmlns:modeler="http://activiti.com/modeler"><![CDATA[true]]></modeler:activiti-idm-assignee>
        <modeler:assignee-info-firstname xmlns:modeler="http://activiti.com/modeler"><![CDATA[test]]></modeler:assignee-info-firstname>
        <modeler:initiator-can-complete xmlns:modeler="http://activiti.com/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
      </extensionElements>
    </userTask>
    <subProcess id="sid-48411614-B7F9-40F3-8154-4EC64E8E4365" name="子流程调用">
      <startEvent id="sid-5BC16FA2-D258-46C8-91E3-D4E615343637"></startEvent>
      <userTask id="sid-05726644-A733-4206-BBB7-4D79B3589ED2" name="子流程环节" activiti:assignee="test">
        <extensionElements>
          <modeler:activiti-idm-assignee xmlns:modeler="http://activiti.com/modeler"><![CDATA[true]]></modeler:activiti-idm-assignee>
          <modeler:assignee-info-firstname xmlns:modeler="http://activiti.com/modeler"><![CDATA[test]]></modeler:assignee-info-firstname>
          <modeler:initiator-can-complete xmlns:modeler="http://activiti.com/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
        </extensionElements>
      </userTask>
      <endEvent id="sid-FB91A674-6633-445D-B4D7-02D8E8BA3992"></endEvent>
      <sequenceFlow id="sid-CC480E20-B61F-4B32-8A16-FC7B724AE4A9" sourceRef="sid-5BC16FA2-D258-46C8-91E3-D4E615343637" targetRef="sid-05726644-A733-4206-BBB7-4D79B3589ED2"></sequenceFlow>
      <sequenceFlow id="sid-D330D43B-09C9-4812-9A80-CAE62F365356" sourceRef="sid-05726644-A733-4206-BBB7-4D79B3589ED2" targetRef="sid-FB91A674-6633-445D-B4D7-02D8E8BA3992"></sequenceFlow>
    </subProcess>
    <sequenceFlow id="sid-A3FBD323-DB9C-48DA-86B4-7723033E3DB3" sourceRef="startEvent1" targetRef="sid-4C9AE06D-43FA-4325-80D5-038F495B46EE"></sequenceFlow>
    <sequenceFlow id="sid-C669A38C-6A62-4F59-8BFF-40D83FA002C2" sourceRef="sid-4C9AE06D-43FA-4325-80D5-038F495B46EE" targetRef="sid-48411614-B7F9-40F3-8154-4EC64E8E4365"></sequenceFlow>
    <userTask id="sid-99E4B39D-36AF-4AE6-B50A-0ECB1CECB67C" name="子流程后" activiti:assignee="$INITIATOR">
      <extensionElements>
        <modeler:activiti-idm-initiator xmlns:modeler="http://activiti.com/modeler"><![CDATA[true]]></modeler:activiti-idm-initiator>
      </extensionElements>
    </userTask>
    <endEvent id="sid-B84A10E5-94AB-4A2F-81C7-708C62421D8D"></endEvent>
    <sequenceFlow id="sid-65ED0CA3-AB95-4788-9D33-26DC86A36BE3" sourceRef="sid-48411614-B7F9-40F3-8154-4EC64E8E4365" targetRef="sid-99E4B39D-36AF-4AE6-B50A-0ECB1CECB67C"></sequenceFlow>
    <sequenceFlow id="sid-27DD695B-3F82-4F7D-8860-979461364E7A" sourceRef="sid-99E4B39D-36AF-4AE6-B50A-0ECB1CECB67C" targetRef="sid-B84A10E5-94AB-4A2F-81C7-708C62421D8D"></sequenceFlow>
  </process>
</definitions>

可以看到<subProcess>元素与主流程其他元素同级,作为主流程的专属属性,其本质上只有一个流程,因此使用主流程的key也能查询出子流程的任务等信息,主子流程的变量信息也是共享的。

2、调用子流程

对应Activiti-app中的

所谓调用子流程,即需要预先定义一个流程实现,然后在主流程中引用该流程的id,完成内嵌,该方式比较灵活且易复用,因此也是子流程使用中最常用的方式,这种子流程是使用<callActivity>标签进行调用,简单的流程图如下:

其主要配置包括 子流程环节所引用的流程进出子流程的变量传递:

引用元素可以是外部流程的某个id,也可以是个变量,进行动态传递

上面的 In 是指主流程在进入子流程时的变量传递配置,Source代表主流程传递的变量名称,Target代表子流程接收的变量名称,还有一个 Out 配置与之同理。

最后保存后的xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef">
  <process id="callActivity" name="调用子流程" isExecutable="true">
    <startEvent id="startEvent1"></startEvent>
    <userTask id="sid-D0BEEE15-A6E8-4077-ACA7-D8C284546BCF" name="子流程前" activiti:assignee="test">
      <extensionElements>
        <modeler:activiti-idm-assignee xmlns:modeler="http://activiti.com/modeler"><![CDATA[true]]></modeler:activiti-idm-assignee>
        <modeler:assignee-info-firstname xmlns:modeler="http://activiti.com/modeler"><![CDATA[test]]></modeler:assignee-info-firstname>
        <modeler:initiator-can-complete xmlns:modeler="http://activiti.com/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
      </extensionElements>
    </userTask>
    <callActivity id="sid-735E518C-DD33-4BD3-A6FA-7A8FEB3A90EF" name="子流程调用" calledElement="simpleModel" activiti:inheritVariables="false">
      <extensionElements>
        <activiti:in source="mainVariable" target="subVariable"></activiti:in>
        <activiti:out source="sub" target="main"></activiti:out>
      </extensionElements>
    </callActivity>
    <endEvent id="sid-333CC74E-46FF-4AB9-8A08-884AD012C90E"></endEvent>
    <sequenceFlow id="sid-E4EE4AE4-E56F-49F3-8AF7-864A76688581" sourceRef="startEvent1" targetRef="sid-D0BEEE15-A6E8-4077-ACA7-D8C284546BCF"></sequenceFlow>
    <sequenceFlow id="sid-99564510-9859-4C04-BBC6-8E1F284AC242" sourceRef="sid-D0BEEE15-A6E8-4077-ACA7-D8C284546BCF" targetRef="sid-735E518C-DD33-4BD3-A6FA-7A8FEB3A90EF"></sequenceFlow>
    <sequenceFlow id="sid-254EBB4A-B061-49AC-9DD7-82B6B24751B5" sourceRef="sid-735E518C-DD33-4BD3-A6FA-7A8FEB3A90EF" targetRef="sid-333CC74E-46FF-4AB9-8A08-884AD012C90E"></sequenceFlow>
  </process>
</definitions>

可以看到调用子流程主要的xml标签为:<callActivity/>以及它的属性calledElement、<activiti:in/>、<activiti:out/>。

由于主子流程是不同的实例,因此在查询子任务时需要使用子流程的key来进行查询。

注意:流程流转到子流程时,子流程的业务键即 Business_key 是为空的,如果需要与主流程保持一致则需要使用到任务监听器,通过变量的形式,先在监听器中先获取主流程的业务键然后以此更新子流程的业务键。

3、事件子流程

对应Activiti-app中的

事件子流程是指通过事件触发的子流程,可以存在于流程级别或子流程级别,用于触发事件子流程的事件,使用启动事件进行配置,因此在事件子流程中不允许使用空启动事件,同时其不允许有任何入口和出口顺序流。

在事件子流程的宿主范围(流程实例或子流程)创建时,创建对启动事件的订阅,当该范围销毁时,删除订阅。

三、总结

嵌入子流程:主子流程本质是同一个流程实例,共享数据

调用子流程:主子流程是不同的实例,但是可以通过监听器方式使得其拥有唯一业务标识,无法通过主流程的key查询子流程的任务,可以通过业务键查询

在实际使用时,Activiti提供的子流程会不满足有些实际业务需求,比如挂起与恢复等等,可使用人工任务进行替代实现。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清茶_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值