使用Camunda流程引擎,关于基于事件的网关(Event-based Gateway)使用

在使用开源Camunda流程引擎做二次开发时,网关是必须要接触的。在Camunda的 Modeler工具中提供了4种类型的网关:Exclusive Gateway(独占网关)、Parallel Gateway(并行网关)、Inclusive Gateway(包容性网关)、Event-based Gateway(基于事件的网关),每一个网关都有自己独特的功能,这一篇就先介绍  Parallel Gateway(并行网关)
Event-based Gateway(基于事件的网关)
The event-based Gateway allows you to make a decision based on events. Each outgoing sequence flow of the gateway needs to be connected to an intermediate catching event. When process execution reaches an event-based Gateway, the gateway acts like a wait state: execution is suspended. In addition, an event subscription is created for each outgoing sequence flow.
大概意思是:    基于事件的网关允许您根据事件做出决定。网关的每个传出序列流都需要连接到中间捕获事件。当进程执行到达基于事件的网关时,网关的作用就像等待状态:执行暂停。此外,为每个传出序列流创建一个事件订阅。
Note that the sequence flows running out of an event-based Gateway are different than ordinary sequence flows. These sequence flows are never actually “executed”. On the contrary, they allow the process engine to determine which events an execution arriving at an event-based Gateway needs to subscribe to. The following restrictions apply:
    * An event-based Gateway must have two or more outgoing sequence flows.
    * An event-based Gateway may only be followed by elements of the type intermediateCatchEvent. (Receive Tasks after an event-based Gateway are not supported by the engine yet.)
    * An intermediateCatchEvent connected to an event-based Gateway must have a single incoming sequence flow.
The following process is an example of a process with an event-based Gateway. When the execution arrives at the event-based Gateway, process execution is suspended. Additionally, the process instance subscribes to the alert signal event and creates a timer which fires after 10 minutes. This effectively causes the process engine to wait for ten minutes for a signal event. If the signal event occurs within 10 minutes, the timer is canceled and execution continues after the signal. If the signal is not fired, execution continues after the timer and the signal subscription is canceled.
大概意思是: 
注意:从基于事件的网关中运行的序列流与普通序列流不同。这些序列流实际上从未被“执行”。相反,它们允许进程引擎确定到达基于事件的网关的执行需要订阅哪些事件。适用以下限制:
  • 基于事件的网关必须有两个或多个传出序列流。
  • 基于事件的网关后面只能是 中间捕获事件类型的元素 。(引擎尚不支持基于事件的网关后接收任务。)
  • 连接到基于事件的网关的中间捕获事件必须具有 单个传入序列流
对于上面的【注意】应该如何理解呢?
  • 如果加了基于事件的网关,后面至少要2个的传出序列,也就是至少要2条分支
  • 每一个分支第一点必须是 中间捕获事件类型的元素
  • 连接到基于事件的网关的中间捕获事件必须具有 单个传入序列流,也就是只能由一个其它地方发出事件让这里的 中间捕获事件捕获到
流程实例
场景:公司里有请假的流程是这样的,组长审批后 ,如果流程3分钟内收到了提醒会走人事审批;如果超过3分钟流程会走经理审批,此选择是2选1,最后走到保存节点。
请假流程图:

 

对这条请假流程理解:流程发起后先经过组长审批,组长审批后流程是牌暂停状态,启动了一个计时器 和 一个信号捕获器;哪一个分支先到就走谁。
节点参数配制:

 

对定时节点,配制一个3分钟的计时

 

对信号捕获节点配制一个捕获的信息。
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:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1qgvkbv" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.11.1" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.15.0">
  <bpmn:process id="Process_0mp91k0" name="基于事件的网关测试" isExecutable="true">
    <bpmn:startEvent id="Event_1lb38ok" name="开始">
      <bpmn:outgoing>Flow_05bilbg</bpmn:outgoing>
    </bpmn:startEvent>
    <bpmn:userTask id="Activity_1a4tbir" name="组长审批">
      <bpmn:incoming>Flow_05bilbg</bpmn:incoming>
      <bpmn:outgoing>Flow_03rgl2c</bpmn:outgoing>
    </bpmn:userTask>
    <bpmn:sequenceFlow id="Flow_05bilbg" sourceRef="Event_1lb38ok" targetRef="Activity_1a4tbir" />
    <bpmn:eventBasedGateway id="Gateway_1b28dvq">
      <bpmn:incoming>Flow_03rgl2c</bpmn:incoming>
      <bpmn:outgoing>Flow_1ncpvea</bpmn:outgoing>
      <bpmn:outgoing>Flow_0tqbbea</bpmn:outgoing>
    </bpmn:eventBasedGateway>
    <bpmn:sequenceFlow id="Flow_03rgl2c" sourceRef="Activity_1a4tbir" targetRef="Gateway_1b28dvq" />
    <bpmn:intermediateCatchEvent id="Event_03ncpx5" name="3分钟">
      <bpmn:incoming>Flow_1ncpvea</bpmn:incoming>
      <bpmn:outgoing>Flow_15s3mjx</bpmn:outgoing>
      <bpmn:timerEventDefinition id="TimerEventDefinition_10clrv0">
        <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">PT3M</bpmn:timeDuration>
      </bpmn:timerEventDefinition>
    </bpmn:intermediateCatchEvent>
    <bpmn:intermediateCatchEvent id="Event_1r3z9cw" name="收到提醒信号">
      <bpmn:incoming>Flow_0tqbbea</bpmn:incoming>
      <bpmn:outgoing>Flow_1k8sox5</bpmn:outgoing>
      <bpmn:signalEventDefinition id="SignalEventDefinition_0i0j6w2" signalRef="Signal_03lqnri" />
    </bpmn:intermediateCatchEvent>
    <bpmn:sequenceFlow id="Flow_1ncpvea" sourceRef="Gateway_1b28dvq" targetRef="Event_03ncpx5" />
    <bpmn:sequenceFlow id="Flow_0tqbbea" sourceRef="Gateway_1b28dvq" targetRef="Event_1r3z9cw" />
    <bpmn:userTask id="Activity_0u5tcj4" name="经理审批">
      <bpmn:incoming>Flow_15s3mjx</bpmn:incoming>
      <bpmn:outgoing>Flow_0q5qrt6</bpmn:outgoing>
    </bpmn:userTask>
    <bpmn:userTask id="Activity_1yshfow" name="人事审批">
      <bpmn:incoming>Flow_1k8sox5</bpmn:incoming>
      <bpmn:outgoing>Flow_164ombm</bpmn:outgoing>
    </bpmn:userTask>
    <bpmn:exclusiveGateway id="Gateway_15od48t">
      <bpmn:incoming>Flow_0q5qrt6</bpmn:incoming>
      <bpmn:incoming>Flow_164ombm</bpmn:incoming>
      <bpmn:outgoing>Flow_1p0r2hw</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:sequenceFlow id="Flow_15s3mjx" sourceRef="Event_03ncpx5" targetRef="Activity_0u5tcj4" />
    <bpmn:sequenceFlow id="Flow_1k8sox5" sourceRef="Event_1r3z9cw" targetRef="Activity_1yshfow" />
    <bpmn:sequenceFlow id="Flow_0q5qrt6" sourceRef="Activity_0u5tcj4" targetRef="Gateway_15od48t" />
    <bpmn:sequenceFlow id="Flow_164ombm" sourceRef="Activity_1yshfow" targetRef="Gateway_15od48t" />
    <bpmn:endEvent id="Event_1ug3xlh" name="结束">
      <bpmn:incoming>Flow_1s0fkbu</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sequenceFlow id="Flow_1p0r2hw" sourceRef="Gateway_15od48t" targetRef="Activity_1xcs7mn" />
    <bpmn:sequenceFlow id="Flow_1s0fkbu" sourceRef="Activity_1xcs7mn" targetRef="Event_1ug3xlh" />
    <bpmn:userTask id="Activity_1xcs7mn" name="保存">
      <bpmn:incoming>Flow_1p0r2hw</bpmn:incoming>
      <bpmn:outgoing>Flow_1s0fkbu</bpmn:outgoing>
    </bpmn:userTask>
  </bpmn:process>
  <bpmn:signal id="Signal_03lqnri" name="signal" />
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_0mp91k0">
      <bpmndi:BPMNEdge id="Flow_05bilbg_di" bpmnElement="Flow_05bilbg">
        <di:waypoint x="228" y="190" />
        <di:waypoint x="300" y="190" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_03rgl2c_di" bpmnElement="Flow_03rgl2c">
        <di:waypoint x="400" y="190" />
        <di:waypoint x="455" y="190" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_1ncpvea_di" bpmnElement="Flow_1ncpvea">
        <di:waypoint x="480" y="165" />
        <di:waypoint x="480" y="120" />
        <di:waypoint x="542" y="120" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_0tqbbea_di" bpmnElement="Flow_0tqbbea">
        <di:waypoint x="480" y="215" />
        <di:waypoint x="480" y="250" />
        <di:waypoint x="542" y="250" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_15s3mjx_di" bpmnElement="Flow_15s3mjx">
        <di:waypoint x="578" y="120" />
        <di:waypoint x="620" y="120" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_1k8sox5_di" bpmnElement="Flow_1k8sox5">
        <di:waypoint x="578" y="250" />
        <di:waypoint x="620" y="250" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_0q5qrt6_di" bpmnElement="Flow_0q5qrt6">
        <di:waypoint x="720" y="120" />
        <di:waypoint x="790" y="120" />
        <di:waypoint x="790" y="165" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_164ombm_di" bpmnElement="Flow_164ombm">
        <di:waypoint x="720" y="250" />
        <di:waypoint x="790" y="250" />
        <di:waypoint x="790" y="215" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_1p0r2hw_di" bpmnElement="Flow_1p0r2hw">
        <di:waypoint x="815" y="190" />
        <di:waypoint x="890" y="190" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_1s0fkbu_di" bpmnElement="Flow_1s0fkbu">
        <di:waypoint x="990" y="190" />
        <di:waypoint x="1072" y="190" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="Gateway_07imvzt_di" bpmnElement="Gateway_1b28dvq">
        <dc:Bounds x="455" y="165" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Event_1hauxts_di" bpmnElement="Event_03ncpx5">
        <dc:Bounds x="542" y="102" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="545" y="83" width="29" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Event_0w7cbdc_di" bpmnElement="Event_1r3z9cw">
        <dc:Bounds x="542" y="232" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="527" y="275" width="66" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_0zdih1c_di" bpmnElement="Activity_0u5tcj4">
        <dc:Bounds x="620" y="80" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_1yshfow_di" bpmnElement="Activity_1yshfow">
        <dc:Bounds x="620" y="210" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Gateway_15od48t_di" bpmnElement="Gateway_15od48t" isMarkerVisible="true">
        <dc:Bounds x="765" y="165" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_0mg5tlh_di" bpmnElement="Activity_1xcs7mn">
        <dc:Bounds x="890" y="150" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Event_1ug3xlh_di" bpmnElement="Event_1ug3xlh">
        <dc:Bounds x="1072" y="172" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="1079" y="215" width="22" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_1a4tbir_di" bpmnElement="Activity_1a4tbir">
        <dc:Bounds x="300" y="150" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Event_1lb38ok_di" bpmnElement="Event_1lb38ok">
        <dc:Bounds x="192" y="172" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="199" y="215" width="22" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>

部署流程并测试验证
因为这里被分为了2种选择,我们来一一测试,首先测试走
定时器这条分支:

 

组长审批后经超过3分钟的等待来到了经理审批节点:

 

信号事件这条分支:

组长审批后,需要在3分钟内产生一个信号让此流程的信号捕获器捕获:
所以需要一个产生信号的地方,这里是写了一个产生信息的接口:
package com.bpm.camunda;

import com.bpm.camunda.dto.WorkflowVariableDto;
import io.swagger.annotations.Api;
import org.camunda.bpm.engine.RuntimeService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;

@RestController
@Api(tags = {"项目接口测试"})
public class TestController {

    @Resource
    private RuntimeService runtimeService;

    @GetMapping("/test")
    public String test(){
        return "123";
    }

    @PostMapping("/sendSignal")
    public String createSign(@RequestBody WorkflowVariableDto dto){
        // 发送信号
        runtimeService.createSignalEvent("signal").setVariables(dto.getVariables()).send();
        return "发送信息";
    }

}
组长审批后过了10秒钟,调用了上面的接口;

 

调用此接口后,流程就走了人事审批 这条分支

 

为了测试是否还会走定时器分支,我还继续等待超过3分钟的时间,仍然还是走的人事审批这条分支流程。
OK关于网关的使用示例到这里就介绍完了,谢谢大家!
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

周周的JAVA技术栈

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

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

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

打赏作者

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

抵扣说明:

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

余额充值