网关用于控制执行流程(或者BPMN 2.0描述的执行令牌)。网关能够消费或生成令牌。
一个网关被图形化地显示为一个菱形,里面有一个图标。该图标显示网关的类型。
1、独家网关
描述
独占网关(也称XOR网关或更专业的基于数据的网关)用于对流程中的决策进行建模。当执行到达这个网关时,所有流出的序列流将按照它们被定义的顺序进行评估。选择条件评估为真的第一个序列流(或者没有条件集,概念上在序列流中定义了“真”)被选择用于继续该过程。
请注意,在这种情况下,输出序列流的语义与BPMN 2.0中的一般情况的语义不同。一般情况下,所有条件评估为真的序列流被选择为以并行方式继续,而在使用专用网关时只选择一个序列流。如果多个序列流具有评估为真的条件,则选择在XML中定义的第一个(并且只有那个!)来继续该过程。如果没有顺序流程可以选择,将会抛出异常。
图形表示法
独家网关被视为一个典型的网关(菱形),里面有一个X图标,指的是XOR语义。请注意,没有图标的网关默认为独占网关。BPMN 2.0规范不允许在同一个进程定义中使用有和没有X的菱形块。
XML表示
独占网关的XML表示法是直接的:一行定义在出站序列流上定义的网关和条件表达式。查看有关条件顺序流程的部分,查看哪些选项可用于此类表达式。
以下面的模型为例:
其中用XML表示如下:
<exclusiveGateway id="exclusiveGw"name="Exclusive Gateway"/>
<sequenceFlow id="flow2"sourceRef="exclusiveGw"targetRef="theTask1">
<conditionExpression xsi:type="tFormalExpression">${input==1}</conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow3"sourceRef="exclusiveGw"targetRef="theTask2">
<conditionExpression xsi:type="tFormalExpression">${input==2}</conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow4"sourceRef="exclusiveGw"targetRef="theTask3">
<conditionExpression xsi:type="tFormalExpression">${input==3}</conditionExpression>
</sequenceFlow>
2、并行网关
描述
网关也可以用来模拟进程中的并发。最直接的网关中的过程模型介绍并发性,是并行网关,它允许你叉成多个执行路径或加入执行的多个传入路径。
并行网关的功能基于输入和输出序列流:
- fork:并行执行所有外发序列流,为每个序列流创建一个并发执行。
- 连接:到达并行网关的所有并发执行都在网关中等待,直到对每个传入序列流执行完毕。然后该过程继续经过加入的网关。
请注意,如果并行网关具有多个传入和传出序列流,并行网关可以同时具有分叉和连接行为。在这种情况下,网关将首先加入所有传入的序列流,然后再分解为多个并发执行路径。
与其他网关类型的一个重要区别是并行网关不评估条件。如果在与并行网关连接的顺序流上定义条件,则简单地忽略它们。
图形表示法
一个并行网关可视化为带有加号的网关(钻石形状),引用AND语义。
XML表示
定义并行网关需要一行XML:
<parallelGateway id="myParallelGateway" />
实际行为(fork,join或both)由连接到并行网关的序列流定义。
例如,上面的模型归结为以下XML:
<startEvent id="theStart" />
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="fork" />
<parallelGateway id="fork" />
<sequenceFlow sourceRef="fork" targetRef="receivePayment" />
<sequenceFlow sourceRef="fork" targetRef="shipOrder" />
<userTask id="receivePayment" name="Receive Payment" />
<sequenceFlow sourceRef="receivePayment" targetRef="join" />
<userTask id="shipOrder" name="Ship Order" />
<sequenceFlow sourceRef="shipOrder" targetRef="join" />
<parallelGateway id="join" />
<sequenceFlow sourceRef="join" targetRef="archiveOrder" />
<userTask id="archiveOrder" name="Archive Order" />
<sequenceFlow sourceRef="archiveOrder" targetRef="theEnd" />
<endEvent id="theEnd" />
在上面的例子中,过程开始后,将创建两个任务:
ProcessInstance pi=runtimeService.startProcessInstanceByKey("forkJoin");
TaskQuery query=taskService.createTaskQuery()
.processInstanceId(pi.getId())
.orderByTaskName()
.asc();
List<Task> tasks=query.list();
assertEquals(2,tasks.size());
Task task1=tasks.get(0);
assertEquals("Receive Payment",task1.getName());
Task task2=tasks.get(1);
assertEquals("Ship Order",task2.getName());
当这两个任务完成后,第二个并行网关将加入这两个执行,并且由于只有一个输出序列流,因此不会创建并发执行路径,只有存档命令任务处于活动状态。
请注意,并行网关不需要平衡(相应并行网关的输入/输出序列流的匹配数量)。并行网关将简单地等待所有进入的序列流,并为每个流出的序列流创建一个并发执行路径,而不受流程模型中其他构造的影响。因此,以下过程在BPMN 2.0中是合法的:
上面文章来自盘古BPM研究院:http://vue.pangubpm.com/
文章翻译提交:https://github.com/qiudaoke/flowable-userguide
了解更多文章可以关注微信公众号: