定义
包容网关可以看做是排他网关和并行网关的结合体。和排他网关一样,你可以在外出顺序流上
定义条件,但与排他网关所不同的是,当进行决策判断时,所有条件为 true 的后继分支都会被依次
执行。如果所有分支条件决策都为 false 且该网关定义了一个默认的连线,那么该默认分支将被执
行。如果没有可执行的分支,则会抛出异常,在流程设计上应避免这种情况发生。包容网关有分支
和合并两种行为:
(1)分支(Fork)
即包容拆分,所有外出顺序流的条件都会被解析,结果为 true 的顺序流会以并行方式继续执行,
会为每个顺序流创建一个分支。如果后继分支可能存在都不通过的情况,应该合理的选择一个默认
路径,否则引擎执行到该网关的分支将被中断于此。
(2)合并(Join)
即包容合并,所有到达包容网关的活动分支路径都汇聚于此等待,直到所有“可以到达”包容
网关的分支路径全部“到达”包容网关,流程才会通过包容网关。这点与并行网关的合并策略是不
同的。引擎判断是否“可以到达”并行网关的路径的逻辑为:计算当前流程实例中的所有执行路径,
检查从其位置是否有一条到达包容网关的路径(忽略顺序流上的任何条件)。如果存在这样的执行
(可到达但尚未到达),则不会触发包容网关的合并行为。
包容网关允许多进多出,如果同一个包容节点有多个进入和外出顺序流,那么它会同时具有分
支和合并功能。网关会先合并所有“可以到达”包容网关的进入顺序流,再根据条件判断结果为 true
的外出顺序流,为它们生成多条并行分支。
图形标记
包容网关显示为一个普通网关(菱形),内部包含一个圆圈图标,如图所示:
XML内容
定义包容网关的 XML 定义如下:
<inclusiveGateway id="inclusiveGateway1" />
包容网关实际的行为(分支,合并或同时分支合并),是由包容网关的流出和流入顺序流决定的。
使用示例
<process id="InclusiveGatewayTest" name="网关-包容网关" isExecutable="true">
<startEvent id="a63caeb191435462eb8fc789b998b0b02" />
<userTask id="a2a3d2965e93841769298862145315216" name="请假申请">
<extensionElements>
<flowable:formData />
<flowable:assigneeType>static</flowable:assigneeType>
</extensionElements>
</userTask>
<sequenceFlow id="a10afa5b876a14ef1927568c25d82532d" sourceRef="a63caeb191435462eb8fc789b998b0b02" targetRef="a2a3d2965e93841769298862145315216" />
<sequenceFlow id="Flow_01gl4se" sourceRef="a2a3d2965e93841769298862145315216" targetRef="Gateway_0wdovry" />
<inclusiveGateway id="Gateway_0wdovry" />
<userTask id="Activity_0n2utd2" name="HR实习生审批">
<extensionElements>
<flowable:formData />
<flowable:assigneeType>static</flowable:assigneeType>
</extensionElements>
</userTask>
<sequenceFlow id="Flow_0poec43" name="天数<3" sourceRef="Gateway_0wdovry" targetRef="Activity_0n2utd2">
<conditionExpression xsi:type="tFormalExpression">${leaveDays<3}</conditionExpression>
</sequenceFlow>
<userTask id="Activity_1jqu87g" name="HR助理审批">
<extensionElements>
<flowable:formData />
<flowable:assigneeType>static</flowable:assigneeType>
</extensionElements>
</userTask>
<sequenceFlow id="Flow_048awuq" name="天数>=3" sourceRef="Gateway_0wdovry" targetRef="Activity_1jqu87g">
<conditionExpression xsi:type="tFormalExpression">${leaveDays>=3}</conditionExpression>
</sequenceFlow>
<userTask id="Activity_0i4f84q" name="直属领导审批">
<extensionElements>
<flowable:formData />
<flowable:assigneeType>static</flowable:assigneeType>
</extensionElements>
</userTask>
<sequenceFlow id="Flow_1ifcgzs" name="天数>=1" sourceRef="Gateway_0wdovry" targetRef="Activity_0i4f84q">
<conditionExpression xsi:type="tFormalExpression">${leaveDays>=1}</conditionExpression>
</sequenceFlow>
<sequenceFlow id="Flow_0evatt3" sourceRef="Activity_0n2utd2" targetRef="Gateway_1byuti3" />
<inclusiveGateway id="Gateway_1byuti3" />
<sequenceFlow id="Flow_1t3shqg" sourceRef="Activity_1jqu87g" targetRef="Gateway_1byuti3" />
<userTask id="Activity_1ox2rws" name="HR经理审批">
<extensionElements>
<flowable:formData />
<flowable:assigneeType>static</flowable:assigneeType>
</extensionElements>
</userTask>
<sequenceFlow id="Flow_0tc6xkx" sourceRef="Gateway_1byuti3" targetRef="Activity_1ox2rws" />
<sequenceFlow id="Flow_0o8l6c2" sourceRef="Activity_1ox2rws" targetRef="Gateway_02v0l7w" />
<inclusiveGateway id="Gateway_02v0l7w" />
<endEvent id="Event_0cvo3tf" />
<sequenceFlow id="Flow_120xxfs" sourceRef="Gateway_02v0l7w" targetRef="Event_0cvo3tf" />
<sequenceFlow id="Flow_0s50mvn" sourceRef="Activity_0i4f84q" targetRef="Gateway_02v0l7w" />
</process>
视频教程
演示demo
本文中内容和案例出自贺波老师的书《深入Activiti流程引擎:核心原理与高阶实战》,书中的介绍更全面、详细,推荐给大家。
深入Activiti流程引擎