首页 > 技术文章 > Camunda 子流程实现实现示例Demo(外部子流程Call Activity)

hibpm 2022-06-13 14:33 原文

Camunda子流程有两种实现方式:嵌套子流程(Embedded Subprocess)和外部子流程(Call Activity)。以下介绍Camunda外部子流程(Call Activity)的实现方式,通过示例介绍主流程如何发起子流程,主子流程间变量如何传递。

一、什么是调用子流程

BPMN 2.0区分了嵌入式子流程(Embedded Subprocess)和调用活动(Call Activity)。从概念上看,当流程执行到达活动时,两者都将调用子流程。

不同之处在于,调用活动引用流程定义外部的流程,而子流程嵌入在原始流程定义中。调用活动的主要用例是拥有可重用的流程定义,可以从多个其他流程定义调用该定义。子流程的流程定义是在运行时解析的。如果需要,也可以独立调用子流程。

当流程执行到达调用活动时,将创建一个新的流程实例,该实例用于执行子流程,可能会像在常规流程中那样创建并行子执行。主流程实例将一直等待,直到子流程完全结束,然后继续原始流程。

二、流程模拟验证

模拟公文处理流程:拟稿人起草公文——》部门会签——》领导签发,其中部门会签通过外部子流程实现。

第一步、设计流程图

设计公文审批主流程:

 


 

设计公文会签子流程:


 

第二步、主子流程关联配置

点击子流程节点,配置要调用哪个子流程。在调用活动中,calledElement属性包含流程定义键,作为对子流程的引用。这意味着总是调用子流程的最新流程定义版本。要调用子流程的另一个版本,可以在调用活动中定义属性calledElementBinding、calledElementVersion和calledElementVersionTag。这些属性是可选的。

 

第三步、主子流程变量传递配置

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

如下图所示,定义主流程变量a1和a2 要分别传递给子流程b1和b2。

 


 

如下图所示,定义子流程变量c1要传递给主流程c2。

 

 

如下图所示,在子流程中通过script脚本模拟生成变量c1,实际业务应用中可以把表单字段传递过来。

 

 

主流程BPMN流程模型文件:

<?xml version="1.0" encoding="UTF-8"?>

<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_031zkxq" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.8.1" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.15.0">

  <bpmn:process id="Process_0z2exxd" name="公文审批主流程" isExecutable="true">

    <bpmn:startEvent id="StartEvent_1">

      <bpmn:outgoing>Flow_0zm80xb</bpmn:outgoing>

    </bpmn:startEvent>

    <bpmn:sequenceFlow id="Flow_0zm80xb" sourceRef="StartEvent_1" targetRef="Activity_1wpmqyf" />

    <bpmn:sequenceFlow id="Flow_0go3jlb" sourceRef="Activity_1wpmqyf" targetRef="Activity_1yu8lt7" />

    <bpmn:sequenceFlow id="Flow_0tp93xf" sourceRef="Activity_1yu8lt7" targetRef="Activity_10emus5" />

    <bpmn:endEvent id="Event_1pnyryf">

      <bpmn:incoming>Flow_036jxrf</bpmn:incoming>

    </bpmn:endEvent>

    <bpmn:sequenceFlow id="Flow_036jxrf" sourceRef="Activity_10emus5" targetRef="Event_1pnyryf" />

    <bpmn:callActivity id="Activity_1yu8lt7" name="部门会签" calledElement="Process_0fqoao8">

      <bpmn:extensionElements>

        <camunda:in source="a1" target="b1" />

        <camunda:in source="a2" target="b2" />

        <camunda:out source="c1" target="c2" />

      </bpmn:extensionElements>

      <bpmn:incoming>Flow_0go3jlb</bpmn:incoming>

      <bpmn:outgoing>Flow_0tp93xf</bpmn:outgoing>

    </bpmn:callActivity>

    <bpmn:userTask id="Activity_10emus5" name="领导签发" camunda:assignee="demo">

      <bpmn:incoming>Flow_0tp93xf</bpmn:incoming>

      <bpmn:outgoing>Flow_036jxrf</bpmn:outgoing>

    </bpmn:userTask>

    <bpmn:userTask id="Activity_1wpmqyf" name="公文起草">

      <bpmn:incoming>Flow_0zm80xb</bpmn:incoming>

      <bpmn:outgoing>Flow_0go3jlb</bpmn:outgoing>

    </bpmn:userTask>

  </bpmn:process>

  <bpmndi:BPMNDiagram id="BPMNDiagram_1">

    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_0z2exxd">

      <bpmndi:BPMNEdge id="Flow_036jxrf_di" bpmnElement="Flow_036jxrf">

        <di:waypoint x="690" y="117" />

        <di:waypoint x="752" y="117" />

      </bpmndi:BPMNEdge>

      <bpmndi:BPMNEdge id="Flow_0tp93xf_di" bpmnElement="Flow_0tp93xf">

        <di:waypoint x="530" y="117" />

        <di:waypoint x="590" y="117" />

      </bpmndi:BPMNEdge>

      <bpmndi:BPMNEdge id="Flow_0go3jlb_di" bpmnElement="Flow_0go3jlb">

        <di:waypoint x="370" y="117" />

        <di:waypoint x="430" y="117" />

      </bpmndi:BPMNEdge>

      <bpmndi:BPMNEdge id="Flow_0zm80xb_di" bpmnElement="Flow_0zm80xb">

        <di:waypoint x="215" y="117" />

        <di:waypoint x="270" y="117" />

      </bpmndi:BPMNEdge>

      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">

        <dc:Bounds x="179" y="99" width="36" height="36" />

      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape id="Event_1pnyryf_di" bpmnElement="Event_1pnyryf">

        <dc:Bounds x="752" y="99" width="36" height="36" />

      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape id="Activity_1k4sxw6_di" bpmnElement="Activity_1yu8lt7">

        <dc:Bounds x="430" y="77" width="100" height="80" />

      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape id="Activity_125gzjf_di" bpmnElement="Activity_10emus5">

        <dc:Bounds x="590" y="77" width="100" height="80" />

      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape id="Activity_0ztm7d3_di" bpmnElement="Activity_1wpmqyf">

        <dc:Bounds x="270" y="77" width="100" height="80" />

      </bpmndi:BPMNShape>

    </bpmndi:BPMNPlane>

  </bpmndi:BPMNDiagram>

</bpmn:definitions>

子流程BPMN流程模型文件:

<?xml version="1.0" encoding="UTF-8"?>

<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_10qlgev" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.8.1" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.15.0">

  <bpmn:process id="Process_0fqoao8" name="公文会签子流程" isExecutable="true">

    <bpmn:startEvent id="StartEvent_1">

      <bpmn:outgoing>Flow_01enblh</bpmn:outgoing>

    </bpmn:startEvent>

    <bpmn:sequenceFlow id="Flow_01enblh" sourceRef="StartEvent_1" targetRef="Activity_1nkq50z" />

    <bpmn:endEvent id="Event_13q9iri">

      <bpmn:incoming>Flow_0ebh7be</bpmn:incoming>

    </bpmn:endEvent>

    <bpmn:sequenceFlow id="Flow_0ebh7be" sourceRef="Activity_1nkq50z" targetRef="Event_13q9iri">

      <bpmn:extensionElements>

        <camunda:executionListener event="take">

          <camunda:script scriptFormat="groovy">def c1 = "hello";

execution.setVariable("c1", c1);</camunda:script>

        </camunda:executionListener>

      </bpmn:extensionElements>

    </bpmn:sequenceFlow>

    <bpmn:userTask id="Activity_1nkq50z" name="会签" camunda:assignee="user1">

      <bpmn:incoming>Flow_01enblh</bpmn:incoming>

      <bpmn:outgoing>Flow_0ebh7be</bpmn:outgoing>

    </bpmn:userTask>

  </bpmn:process>

  <bpmndi:BPMNDiagram id="BPMNDiagram_1">

    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_0fqoao8">

      <bpmndi:BPMNEdge id="Flow_0ebh7be_di" bpmnElement="Flow_0ebh7be">

        <di:waypoint x="370" y="117" />

        <di:waypoint x="432" y="117" />

      </bpmndi:BPMNEdge>

      <bpmndi:BPMNEdge id="Flow_01enblh_di" bpmnElement="Flow_01enblh">

        <di:waypoint x="215" y="117" />

        <di:waypoint x="270" y="117" />

      </bpmndi:BPMNEdge>

      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">

        <dc:Bounds x="179" y="99" width="36" height="36" />

      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape id="Event_13q9iri_di" bpmnElement="Event_13q9iri">

        <dc:Bounds x="432" y="99" width="36" height="36" />

      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape id="Activity_1m91lyj_di" bpmnElement="Activity_1nkq50z">

        <dc:Bounds x="270" y="77" width="100" height="80" />

      </bpmndi:BPMNShape>

    </bpmndi:BPMNPlane>

  </bpmndi:BPMNDiagram>

</bpmn:definitions>

第四步、发起主流程

通过demo用户登录camunda平台http://localhost:8080/camunda/app/tasklist/default/#/login,发起主流程:

填写流程变量a1和a2:

 

启动流程后,此时流程在主流程第一个活动节点,点击提交流程,将自动激活子流程。

 

查看此时主流程的流程变量:

 

第五步、启动子流程

主流程点击提交,流程执行到达子流程调用活动,将创建一个新的流程实例,该实例用于执行子流程,此时主流程实例将一直等待,直到子流程完全结束,然后继续原始流程。通过user1登录查看子流程待办,并提交待办任务。

 

 

查看子流程的流程变量,发现主流程变量a1和a2分别传递了过来,自动映射为b1和b2。

user1登录系统,查看子流程待办任务,提交任务,子流程结束,流程自动回到主流程。

 

 

此时查看主流程变量,发现子流程变量c1成功返回给了主流程,自动映射为名称c2 。


 

通过以上演示了camunda如何配置子流程、如何发起子流程、主子流程间如何传递变量,详细请查看官方文档。

 

参考:

Call Activity | docs.camunda.org

http://www.yunchengxc.com

推荐阅读