网关
概览
网关(Gateway)用于控制流程的流向,可以决定在什么条件下流程往哪个方向继续前进。 每种类型的网关都有特定的用途,根据特定条件或事件引导流程的流向。
使用网关可以对流程中的决策点、分支、合并和同步进行建模, 可以更准确地表示更复杂以及动态的流程。
网关类型
Jmix BPM 支持 4 种类型的 BPMN 网关:
-
排他网关(Exclusive)
-
并行网关(Parallel)
-
包容网关(Inclusive)
-
事件网关(Event-based)
不支持 复杂网关(Complex gateway)。
分支与合并
除了事件网关外,其他的网关都可以在流程建模中扮演两个角色:
-
分支(fork) — 流程在这里分为几个不同的路径
-
合并(join) — 流程在这里合并
通常,分支和合并网关是配对的,但这也不是强制条件。 如果流程产生了分支,每个路径都可以继续,直至遇到结束事件。
网关通过生成或使用 tokens 控制流程的执行流向。 |
排他网关
排他(Exclusive)网关,也叫异或(XOR)网关,用于根据数据对流程中的决策进行建模,例如, 根据流程变量值或 Bean 方法返回的值进行决策。
当流程执行到达这种网关时, 与传出顺序流关联的所有条件都按定义的顺序进行计算。
其中 第一个 条件计算结果为 true 的顺序流将选为流程继续的方向。 空条件始终视为 true。
这里的 “第一个”,是指 XML 文件中定义的顺序流的顺序, 不一定是在网关描述中显示的顺序。
这种区别强调的是,流的顺序是基于 XML 文件结构, 而非网关中流的可视化表示或文本描述。
人们经常使用疑问句作为排他网关的名称。 例如,“文档是否已获得批准?”,但是网关本身也许没有任何内部逻辑。 网关真正能工作的前提,是必须在传出流上定义条件。
条件
条件用于定义何时可以选取该路径。在 Jmix BPM 中,条件可以有以下来源:
-
表达式(Expression)
-
用户任务输出(User task outcomes)
-
业务规则任务结果(Business rule task result)
仔细检查是否定义了所有必需的传出流条件。 否则,如果没定义,则选择第一个路径。 箭头上的文本标签对 BPM 引擎不表示任何意义。 |
表达式
这是一个布尔表达式,可以访问流程变量并将其与文本或其他变量进行比较。 同样,也可以在这里调用 Spring bean 的方法。
示例:
${orderAmount > 1000} ${price > 100 && price <= 500} ${accountant.username == "jane"} ${jbt_MyService.getRandom > 0.5} ${jbt_MyService.evaluateCondition()}
最后一个情况中,方法需要返回 boolean 值。
用户任务输出
如果流程中有一个带输出的用户任务,可以选择其中一个输出用于激活给定的流。
设置基于输出的条件,首先选择一个用户任务,然后选择输出。
当选择用户任务作为条件时,请确保用户任务在条件计算 之前 执行。 否则,会引起运行时错误。
条件和多实例用户任务
当用户任务是 多实例 时, 会显示一个额外的参数 — condition type:
支持以下选项:
-
一人完成即可(Anyone completed with the outcome)
-
每人都需完成(Everyone completed with the outcome)
-
无人完成(No one completed with the outcome)
使用这个参数可以实现某种形式的投票。 例如,可以只要一个用户完成任务并产生 'yes' 的输出即可选择该路径。
业务规则任务结果
一个 业务规则 任务返回的结果 可以用在网关的条件中。
如需基于业务规则结果设置条件, 需要选择业务规则任务、决策表输出变量以及输出值。
请确保选择的业务规则任务在网关 之前 执行。
使用排他网关
独立的分支和合并
从形式上讲,BPMN 规范允许同一个网关扮演传入和传出两个角色,但是这种用法是强烈不推荐的。
因此,请避免使用如下图所示的排他网关,该网关既是分支又是合并:
最好将网关的角色分开,如下图所示,有两个网关,一个用于合并,另一个用于分支:
多个条件为真
在此示例中,可以看到排他网关的两个条件都明显为真。 但是首先会计算条件 #1,因为在 XML 中,#1 定义的位置高于 #2。 但是,在网关的描述中,条件 #2 在最前面。
<process id="exclusion-gateway-demo" name="exclusion-gateway-demo" isExecutable="true">
<exclusiveGateway id="Gateway_0r2ejfv"> (3)
<incoming>Flow_1sjggq6</incoming>
<outgoing>Flow_2</outgoing>
<outgoing>Flow_1</outgoing>
</exclusiveGateway>
<endEvent id="Event_0kn6j1t" name="1">
<incoming>Flow_1</incoming>
</endEvent>
<sequenceFlow id="Flow_1" name="1 > 0" sourceRef="Gateway_0r2ejfv" targetRef="Event_0kn6j1t"> (2)
<extensionElements>
<jmix:conditionDetails conditionSource="expression" />
</extensionElements>
<conditionExpression xsi:type="tFormalExpression">${1>0}</conditionExpression>
</sequenceFlow>
<endEvent id="Event_1wmb937" name="2">
<incoming>Flow_2</incoming>
</endEvent>
<sequenceFlow id="Flow_2" name="2 > 0" sourceRef="Gateway_0r2ejfv" targetRef="Event_1wmb937"> (1)
<extensionElements>
<jmix:conditionDetails conditionSource="expression" />
</extensionElements>
<conditionExpression xsi:type="tFormalExpression">${2>0}</conditionExpression>
</sequenceFlow>
<startEvent id="Event_15w11z6">
<outgoing>Flow_1sjggq6</outgoing>
</startEvent>
<sequenceFlow id="Flow_1sjggq6" sourceRef="Event_15w11z6" targetRef="Gateway_0r2ejfv" />
</process>
1 | — 条件 #1 顺序流 |
2 | — 条件 #2 顺序流 |
3 | — 网关描述部分,条件 #2 在 #1 之前 |
并行网关
并行网关(parallel gateway),也称为 AND 网关,用于将流程拆分为多个并行路径, 或者将多个并行路径合并至单个流中。
当流程执行到达并行网关时,流程的路径按传出流数进行分叉。
如果存在合并并行网关,则流程将等待,直到所有传入流执行完毕。 即,等待所有并行路径都到达合并网关。 然后,流程经过合并网关继续。
实际上,将并行路径全部合并也不是必需的。 每个路径都可以有自己的 结束事件。 但是整个流程只有在 全部 并行路径完成后才结束。
包容网关
包容网关(Inclusive gateway),也称 OR 网关,可以看作是 排他 和 并行 网关的组合。
与排他网关一样,可以在传出顺序流上定义条件,包容网关将计算这些条件。
但主要区别在于,包容网关可以有多个顺序流,这点与并行网关一样。
但是与并行网关不同在于,包容网关只等待将要执行的传入流(条件为真)。 分支合并后,流程经过包容网关继续。
在此示例中,第一个用户填写一个表格,标记必须参与审批流程的人员。 与并行流程不同,只有选定的员工才会收到审批任务。
假设选则了一个 Accountant 和一个 Team leader。 然后 合并 网关会等待,直到这两个员工都完成任务。
事件网关
事件网关(Event-based gateway)提供了一种根据事件做出决策的方法。
事件网关必须至少有两个传出顺序流。 每个顺序流都必须连接一个中间捕获事件,捕获事件的类型可以为定时器、消息或信号。
不允许在事件网关之后立即执行其他活动。
当流程执行到达事件网关时,网关的行为类似于 等待状态:暂停执行。
然后,对于每个传出顺序流,都会创建一个事件订阅。
哪个事件首先触发,流程将向哪个分支前进。
请注意,从事件网关的顺序流与普通顺序流不同。 这些顺序流并没有实际“执行”。 而是, 流程引擎可以确定需要订阅哪些事件以及到达 事件网关 的执行活动。