【flowable专栏】网关类型

1.排他网关(Exclusive Gateway)

这个可以说是我们最最最常用的一个网关了,实际上可以理解为if-else。

常见场景:金额报销

注意:条件可以有多个,但是为true的情况必须要有且只能有一个,否则会报错。

建议:添加一个默认的路径,防止全false的情况。

例子:

xml 复制代码
<process id="flow_fxbn4kjb" name="flow_mdrr27se">
    <startEvent id="start_event" name="开始">
      <outgoing>Flow_0dso2ii</outgoing>
    </startEvent>
    <userTask id="Activity_1b7dkwh" name="审批人A">
      <incoming>Flow_0dso2ii</incoming>
      <outgoing>Flow_1h46vbf</outgoing>
    </userTask>
    <sequenceFlow id="Flow_0dso2ii" sourceRef="start_event" targetRef="Activity_1b7dkwh" />
    <exclusiveGateway id="Gateway_0gs8sp7" name="排斥网关">
      <incoming>Flow_1h46vbf</incoming>
      <outgoing>Flow_09abes7</outgoing>
      <outgoing>Flow_0xb14rh</outgoing>
    </exclusiveGateway>
    <sequenceFlow id="Flow_1h46vbf" sourceRef="Activity_1b7dkwh" targetRef="Gateway_0gs8sp7" />
    <userTask id="Activity_1ugsmv9" name="审核人B">
      <incoming>Flow_09abes7</incoming>
      <outgoing>Flow_0guuy54</outgoing>
    </userTask>
    <sequenceFlow id="Flow_09abes7" sourceRef="Gateway_0gs8sp7" targetRef="Activity_1ugsmv9">
      <conditionExpression xsi:type="tFormalExpression">${amount &amp;lt; 1000}</conditionExpression>
    </sequenceFlow>
    <userTask id="Activity_1g0kati" name="审核人C">
      <incoming>Flow_0xb14rh</incoming>
      <outgoing>Flow_17yxqht</outgoing>
    </userTask>
    <sequenceFlow id="Flow_0xb14rh" sourceRef="Gateway_0gs8sp7" targetRef="Activity_1g0kati">
      <conditionExpression xsi:type="tFormalExpression">${amount &amp;gt;= 1000}</conditionExpression>
    </sequenceFlow>
    <endEvent id="Event_00bedoo" name="结束">
      <incoming>Flow_0guuy54</incoming>
      <incoming>Flow_17yxqht</incoming>
    </endEvent>
    <sequenceFlow id="Flow_0guuy54" sourceRef="Activity_1ugsmv9" targetRef="Event_00bedoo" />
    <sequenceFlow id="Flow_17yxqht" sourceRef="Activity_1g0kati" targetRef="Event_00bedoo" />
  </process>

2.并行网关(Parallel Gateway)

简单来说,就是先分叉再相聚,所有路线一起走,最后等待全部到齐再往后走。

ps:不是说一定要有一个分叉和聚合得并行网关,但是更推荐这样。

并行网关机制:内置计数器,等所有分支都到达才放行一次。

下面分几种情况分析:

不用网关,汇聚点是任务节点,会执行多次,按照先后顺序。

排斥网关,无计数器,每条分支到达都判断条件,满足即放行 → 后续可能执行多次。

唯一可用场景:后续节点是无状态通知(发邮件、发短信),重复执行无影响。

包容网关,内置活跃分支计数器,等所有活跃分支到达才放行一次,可模拟并行网关。但 性能略差(包容网关计算更复杂),无实际收益。

事件网关,只能聚合捕获事件,谁先到谁走,其他事件自动失效。

适用场景:B 和 C 谁先完成,就走谁的后续逻辑,互斥,不汇总。

总的来说,最好还是按照规范来,这样才是最好的实现方案。

例子:

xml 复制代码
<process id="flow_fxbn4kjb" name="flow_mdrr27se">
    <startEvent id="start_event" name="开始">
      <outgoing>Flow_0dso2ii</outgoing>
    </startEvent>
    <userTask id="Activity_1b7dkwh" name="审批人A">
      <incoming>Flow_0dso2ii</incoming>
      <outgoing>Flow_1h46vbf</outgoing>
    </userTask>
    <sequenceFlow id="Flow_0dso2ii" sourceRef="start_event" targetRef="Activity_1b7dkwh" />
    <sequenceFlow id="Flow_1h46vbf" sourceRef="Activity_1b7dkwh" targetRef="Gateway_0gs8sp7" />
    <userTask id="Activity_1ugsmv9" name="审核人B">
      <incoming>Flow_09abes7</incoming>
      <outgoing>Flow_1xq7lef</outgoing>
    </userTask>
    <sequenceFlow id="Flow_09abes7" sourceRef="Gateway_0gs8sp7" targetRef="Activity_1ugsmv9" />
    <userTask id="Activity_1g0kati" name="审核人C">
      <incoming>Flow_0xb14rh</incoming>
      <outgoing>Flow_1yb8tzu</outgoing>
    </userTask>
    <sequenceFlow id="Flow_0xb14rh" sourceRef="Gateway_0gs8sp7" targetRef="Activity_1g0kati" />
    <parallelGateway id="Gateway_0gs8sp7" name="并行网关(分叉)">
      <incoming>Flow_1h46vbf</incoming>
      <outgoing>Flow_09abes7</outgoing>
      <outgoing>Flow_0xb14rh</outgoing>
    </parallelGateway>
    <exclusiveGateway id="Gateway_0rgnps9" name="并行网关(聚合)">
      <incoming>Flow_1xq7lef</incoming>
      <incoming>Flow_1yb8tzu</incoming>
      <outgoing>Flow_0ue04bt</outgoing>
    </exclusiveGateway>
    <sequenceFlow id="Flow_1xq7lef" sourceRef="Activity_1ugsmv9" targetRef="Gateway_0rgnps9" />
    <sequenceFlow id="Flow_1yb8tzu" sourceRef="Activity_1g0kati" targetRef="Gateway_0rgnps9" />
    <userTask id="Activity_1bmja5f" name="审批人D">
      <incoming>Flow_0ue04bt</incoming>
      <outgoing>Flow_1mgv6yk</outgoing>
    </userTask>
    <sequenceFlow id="Flow_0ue04bt" sourceRef="Gateway_0rgnps9" targetRef="Activity_1bmja5f" />
    <endEvent id="Event_10q405i" name="结束">
      <incoming>Flow_1mgv6yk</incoming>
    </endEvent>
    <sequenceFlow id="Flow_1mgv6yk" sourceRef="Activity_1bmja5f" targetRef="Event_10q405i" />
  </process>

3.包容网关(Inclusive Gateway)

简单来说,就是符合条件的都一起走,最后等待所有活跃分支聚合再往后走。

ps:聚合网关会自动统计实际走了几条,无需手动维护计数器。

部分代码:

复制代码
    <startEvent id="start_event" name="开始">
      <outgoing>Flow_1v1pr17</outgoing>
    </startEvent>
    <userTask id="Activity_0u17ax3" name="A">
      <incoming>Flow_1v1pr17</incoming>
      <outgoing>Flow_1t6ea6k</outgoing>
    </userTask>
    <sequenceFlow id="Flow_1v1pr17" sourceRef="start_event" targetRef="Activity_0u17ax3" />
    <sequenceFlow id="Flow_1t6ea6k" sourceRef="Activity_0u17ax3" targetRef="Gateway_0dxg1cd" />
    <inclusiveGateway id="Gateway_0dxg1cd" name="包容网关(分叉)">
      <incoming>Flow_1t6ea6k</incoming>
      <outgoing>Flow_1bg6ule</outgoing>
      <outgoing>Flow_1fu8vbk</outgoing>
      <outgoing>Flow_1rtdmr0</outgoing>
    </inclusiveGateway>
    <userTask id="Activity_0pk0yx4" name="B">
      <incoming>Flow_1bg6ule</incoming>
      <outgoing>Flow_03pazic</outgoing>
    </userTask>
    <sequenceFlow id="Flow_1bg6ule" sourceRef="Gateway_0dxg1cd" targetRef="Activity_0pk0yx4">
      <conditionExpression xsi:type="tFormalExpression">${num &amp;gt; 100}</conditionExpression>
    </sequenceFlow>
    <userTask id="Activity_11j4upm" name="C">
      <incoming>Flow_1fu8vbk</incoming>
      <outgoing>Flow_1wa18oz</outgoing>
    </userTask>
    <sequenceFlow id="Flow_1fu8vbk" sourceRef="Gateway_0dxg1cd" targetRef="Activity_11j4upm">
      <conditionExpression xsi:type="tFormalExpression">${num &amp;le; 0}</conditionExpression>
    </sequenceFlow>
    <userTask id="Activity_0578vsx" name="D">
      <incoming>Flow_1rtdmr0</incoming>
      <outgoing>Flow_03k6sdm</outgoing>
    </userTask>
    <sequenceFlow id="Flow_1rtdmr0" sourceRef="Gateway_0dxg1cd" targetRef="Activity_0578vsx">
      <conditionExpression xsi:type="tFormalExpression">${num &amp;lt; 100}</conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="Flow_1wa18oz" sourceRef="Activity_11j4upm" targetRef="Gateway_05le2zp" />
    <inclusiveGateway id="Gateway_05le2zp" name="包容网关(聚合)">
      <incoming>Flow_1wa18oz</incoming>
      <incoming>Flow_03pazic</incoming>
      <incoming>Flow_03k6sdm</incoming>
      <outgoing>Flow_1i51oo7</outgoing>
    </inclusiveGateway>
    <sequenceFlow id="Flow_03pazic" sourceRef="Activity_0pk0yx4" targetRef="Gateway_05le2zp" />
    <sequenceFlow id="Flow_03k6sdm" sourceRef="Activity_0578vsx" targetRef="Gateway_05le2zp" />
    <userTask id="Activity_0jpa4wc" name="E">
      <incoming>Flow_1i51oo7</incoming>
      <outgoing>Flow_1wtf8oo</outgoing>
    </userTask>
    <sequenceFlow id="Flow_1i51oo7" sourceRef="Gateway_05le2zp" targetRef="Activity_0jpa4wc" />
    <endEvent id="Event_1eisxie" name="结束">
      <incoming>Flow_1wtf8oo</incoming>
    </endEvent>
    <sequenceFlow id="Flow_1wtf8oo" sourceRef="Activity_0jpa4wc" targetRef="Event_1eisxie" />
  </process>

4.事件网关(Event-Based Gateway)

简单来说,就是谁先发生就谁生效,其他事件不生效。

注意:

A 事件网关后只能跟捕获事件()

B 一旦某个事件触发,其他事件自动失效

C 不能与 userTask 直连。

部分代码:

xml 复制代码
<process id="orderPayment" name="订单支付处理" isExecutable="true">
    <startEvent id="start"/>
    <sequenceFlow sourceRef="start" targetRef="apply"/>

    <!-- 2. 用户下单 -->
    <userTask id="apply" name="提交订单" flowable:assignee="${userId}"/>
    <sequenceFlow sourceRef="apply" targetRef="eventGate"/>

    <!-- 3. 事件网关:等待第一个发生的事件 -->
    <eventBasedGateway id="eventGate"/>
    <sequenceFlow sourceRef="eventGate" targetRef="waitPayment"/>
    <sequenceFlow sourceRef="eventGate" targetRef="waitTimeout"/>

    <!-- 4. 消息事件:等待支付回调 -->
    <intermediateCatchEvent id="waitPayment" name="等待支付">
      <messageEventDefinition messageRef="msgPaymentSuccess"/>
    </intermediateCatchEvent>
    <sequenceFlow sourceRef="waitPayment" targetRef="confirmPayment"/>
    <serviceTask id="confirmPayment" name="确认支付成功"
                 flowable:delegateExpression="${confirmPaymentDelegate}"/>
    <sequenceFlow sourceRef="confirmPayment" targetRef="end1"/>
    <endEvent id="end1"/>

    <!-- 5. 定时器事件:30分钟超时 -->
    <intermediateCatchEvent id="waitTimeout" name="30分钟超时">
      <timerEventDefinition>
        <timeDuration>PT30M</timeDuration>
      </timerEventDefinition>
    </intermediateCatchEvent>
    <sequenceFlow sourceRef="waitTimeout" targetRef="autoCancel"/>
    <serviceTask id="autoCancel" name="自动取消订单"
                 flowable:delegateExpression="${cancelOrderDelegate}"/>
    <sequenceFlow sourceRef="autoCancel" targetRef="end2"/>
    <endEvent id="end2"/>
  </process>

5.小结

排他 = if-else

并行 = fork-join

包容 = if-else 且 可以多条 true

事件 = 等谁先发生(只能连捕获)

相关推荐
晚风吹长发1 天前
初步了解Linux中的动静态库及其制作和使用
linux·运维·服务器·数据结构·c++·后端·算法
梁下轻语的秋缘1 天前
ESP32-WROOM-32E存储全解析:RAM/Flash/SD卡读写与速度对比
java·后端·spring
wanzhong23331 天前
开发日记8-优化接口使其更规范
java·后端·springboot
羊小猪~~1 天前
【QT】--文件操作
前端·数据库·c++·后端·qt·qt6.3
张彦峰ZYF1 天前
商品供给域的工程化简要设计考量
后端·系统架构·商品模型·商品供给
小北方城市网1 天前
微服务注册中心与配置中心实战(Nacos 版):实现服务治理与配置统一
人工智能·后端·安全·职场和发展·wpf·restful
爬山算法1 天前
Hibernate(47)Hibernate的会话范围(Scope)如何控制?
java·后端·hibernate
源码宝2 天前
云HIS二次开发实施路径指南
后端·源码·二次开发·saas·云his·医院信息系统
李慕婉学姐2 天前
Springboot旅游景点管理系统2fj40iq6(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
蓝眸少年CY2 天前
(第八篇)spring cloud之zuul路由网关
后端·spring·spring cloud