天天看點

(二)BPMN2.0規範介紹——4網關 Gateways一、定義二、排他網關 Exclusive Gateway三、并行網關 Parallel Gateway四、包容網關 Inclusive Gateway五、基于事件的網關 Event­based Gateway

目錄

一、定義

二、排他網關 Exclusive Gateway

三、并行網關 Parallel Gateway

四、包容網關 Inclusive Gateway

五、基于事件的網關 Event­based Gateway

一、定義

網關用于控制執行的流向(或者按BPMN 2.0描述的,執行的token 标志)。網關可以消耗與生成标志。

網關用其中帶有圖示的菱形表示。該圖示顯示了網關的類型

(二)BPMN2.0規範介紹——4網關 Gateways一、定義二、排他網關 Exclusive Gateway三、并行網關 Parallel Gateway四、包容網關 Inclusive Gateway五、基于事件的網關 Event­based Gateway

二、排他網關 Exclusive Gateway

  • 描述:

排他網關(也叫異或網關 XOR gateway,或者更專業的,基于資料的排他網關 exclusive data­based gateway),用于為流程中的決策模組化。當執行到達這個網關時,所有出口順序流會按照它們定義的順序進行計算。條件計算為true的順序流(當沒有設定條件時,認為順序流定義為true)會被選擇用于繼續流程。

請注意這裡出口順序流的含義與BPMN 2.0中的一般情況不一樣。一般情況下,所有條件計算為true的順序流,都會被選擇繼續,并行執行。而使用排他網關時,隻會選擇一條順序流。當多條順序 流的條件都計算為true時,其中在XML中定義的第一條(也隻有這條)會被選擇,用于繼續流程。如果沒有可選的順序流,會抛出異常。

  • 圖示:
排他網關,用内部帶有’X’圖示的标準網關(菱形)表示,'X’圖示代表異或(XOR)的含義。請注意内部沒有圖示的網關預設為排他網關。BPMN 2.0規範不允許在同一個流程中,混合使用帶有及沒有X的菱形标志。
(二)BPMN2.0規範介紹——4網關 Gateways一、定義二、排他網關 Exclusive Gateway三、并行網關 Parallel Gateway四、包容網關 Inclusive Gateway五、基于事件的網關 Event­based Gateway
  • java代碼:
  •  xml表示:

排他網關的XML表示格式很直接:一行定義網關的XML,而條件表達式定義在出口順序流上。檢視條件順序流章節了解這種表達式的可用選項。

以下面的模型為例:

(二)BPMN2.0規範介紹——4網關 Gateways一、定義二、排他網關 Exclusive Gateway三、并行網關 Parallel Gateway四、包容網關 Inclusive Gateway五、基于事件的網關 Event­based Gateway
<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>
           

三、并行網關 Parallel Gateway

  • 描述:

網關也可以用于對流程中并行的模組化。在流程模型中引入并行的最簡單的網關,就是并行網關。它可以将執行分支(fork)為多條路徑,也可以合并(join)執行的多條入口路徑。

并行網關的功能,基于其入口與出口順序流:

(1)分支:所有的出口順序流都并行執行,為每一條順序流建立一個并行執行。

(2)合并:所有到達并行網關的并行執行,都在網關處等待,直到每一條入口順序流都有一個執行到達。然後流程經過該合并網關繼續。

請注意,如果并行網關同時具有多條入口與出口順序流,可以同時具有分支與合并的行為。在這種情況下,網關首先合并所有入口順序流,然後分裂為多條并行執行路徑。

與其他網關類型的重要差別,是并行網關不計算條件。如果連接配接到并行網關的順序流上定義了條件,條件會被簡單地忽略。

  • 圖示:
并行網關,用内部帶有’加号’圖示的網關(菱形)表示,代表與(AND)的含義。
(二)BPMN2.0規範介紹——4網關 Gateways一、定義二、排他網關 Exclusive Gateway三、并行網關 Parallel Gateway四、包容網關 Inclusive Gateway五、基于事件的網關 Event­based Gateway
  • java代碼:
在上面的例子中,當流程啟動後,會建立兩個任務:
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());
           

 當這兩個任務完成後,第二個并行網關會合并這兩個執行,并且由于隻有一條出口順序流,不會再建立并行執行路徑,隻會激活ArchiveOrder(存檔訂單)任務。

請注意并行網關不需要“平衡”(也就是說,對應的并行網關,其入口/出口順序流的數量不需要比對)。并行網關會簡單地等待所有入口順序流,并為每一條出口順序流建立并行執行,不受流程模型中的其他結構影響。是以,下面的流程在BPMN 2.0中是合法的:

(二)BPMN2.0規範介紹——4網關 Gateways一、定義二、排他網關 Exclusive Gateway三、并行網關 Parallel Gateway四、包容網關 Inclusive Gateway五、基于事件的網關 Event­based Gateway
  •  xml表示:
定義并行網關需要一行XML:
<parallelGateway id="myParallelGateway" />

實際行為(分支,合并或兩者皆有),由連接配接到該并行網關的順序流定義。
例如,上面的模型表現為下面的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" />
           

四、包容網關 Inclusive Gateway

  • 描述:

包容網關可被視作排他網關與并行網關的組合。與排他網關一樣,可以在出口順序流上定義條件,包容網關會計算它們。然而主要的差別是,包容網關與并行網關一樣,可以選擇多于一條(出口)順序流。

包容網關的功能,基于其入口與出口順序流:

(1)分支:所有出口順序流的條件都會被計算,對于條件計算為true的順序流,流程會并行地沿其繼續,為每一條順序流建立一個并行執行。

(2)合并:所有到達包容網關的并行執行,都會在網關處等待,直到每一條具有流程标志的入口順序流,都有一個執行到達。這是與并行網關的重要差別。換句話說,包容網關隻會等待将會被執行的入口順序流。在合并後,流程穿過合并并行網關繼續。

請注意,如果包容網關同時具有多條入口與出口順序流,可以同時具有分支與合并的行為。在這種情況下,網關首先合并所有具有流程标志的入口順序流,然後為條件計算為true的出口順序流,分裂為多條并行執行路徑

  • 圖示:
包容網關,用内部帶有’圓圈’圖示的網關(菱形)表示。
(二)BPMN2.0規範介紹——4網關 Gateways一、定義二、排他網關 Exclusive Gateway三、并行網關 Parallel Gateway四、包容網關 Inclusive Gateway五、基于事件的網關 Event­based Gateway
  • java代碼:
在上面的例子中,當流程啟動後,如果流程變量paymentReceived == false且shipOrder == true,将會建立兩個任務。如果隻有一個流程變量等于true,則隻會建立一個任務。如果沒有條件計算為true,會抛出異常,并可通過指定默出口順序 流避免。在下面的例子中,隻有ship order(傳遞訂單)一個任務會被建立:
HashMap<String, Object> variableMap = new HashMap<String, Object>();
variableMap.put("receivedPayment", true);
variableMap.put("shipOrder", true);
ProcessInstance pi = runtimeService.startProcessInstanceByKey("forkJoin");
TaskQuery query = taskService.createTaskQuery()
.processInstanceId(pi.getId())
.orderByTaskName()
.asc();
List<Task> tasks = query.list();
assertEquals(1, tasks.size());
Task task = tasks.get(0);
assertEquals("Ship Order", task.getName());
           

當這個任務完成後,第二個包容網關會合并這兩個執行,并且由于隻有一條出口順序流,不會再建立并行執行路徑,隻會激活ArchiveOrder(存檔訂單)任務。

請注意包容網關不需要“平衡”(也就是說,對應的包容網關,其入口/出口順序流的數量不需要比對)。包容網關會簡單地等待所有入口順序流,并為每一條出口順序流建立并行執行,不受流程模型中的其他結構影響。

  •  xml表示:
定義包容網關需要一行XML:
<inclusiveGateway id="myInclusiveGateway" />

實際行為(分支,合并或兩者皆有),由連接配接到該包容網關的順序流定義。
例如,上面的模型表現為下面的XML:

<startEvent id="theStart" />
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="fork" />
<inclusiveGateway id="fork" />
<sequenceFlow sourceRef="fork" targetRef="receivePayment" >
    <conditionExpression xsi:type="tFormalExpression">
        ${paymentReceived == false}
    </conditionExpression>
</sequenceFlow>
<sequenceFlow sourceRef="fork" targetRef="shipOrder" >
    <conditionExpression xsi:type="tFormalExpression">
        ${shipOrder == true}
    </conditionExpression>
</sequenceFlow>
<userTask id="receivePayment" name="Receive Payment" />
<sequenceFlow sourceRef="receivePayment" targetRef="join" />
<userTask id="shipOrder" name="Ship Order" />
<sequenceFlow sourceRef="shipOrder" targetRef="join" />
<inclusiveGateway id="join" />
<sequenceFlow sourceRef="join" targetRef="archiveOrder" />
<userTask id="archiveOrder" name="Archive Order" />
<sequenceFlow sourceRef="archiveOrder" targetRef="theEnd" />
<endEvent id="theEnd" />
           

五、基于事件的網關 Event­based Gateway

  • 描述:

基于事件的網關,允許基于事件做選擇。網關的每一條出口順序流,都需要連接配接至一個捕獲中間事件。當流程執行到達基于事件的網關時,網關類似等待狀态地動作:執行被暫停。并且,為每一條出口順序流,建立一個事件訂閱。

請注意基于事件的網關,其出口順序流與一般的順序流不同。這些順序流從不實際被執行。相反,它們允許流程引擎決定,當執行到達一個基于事件的網關時,需要訂閱什麼事件。基于下列限制:

(1)一個基于事件的網關,必須有兩條或更多的出口順序流。

(2)基于事件的網關,隻能連接配接至 intermediateCatchEvent(捕獲中間事件) 類型的元素(Activiti不支援基于事件的網關後,連接配接接收任務,Receive Task)。

(3)連接配接至基于事件的網關的 intermediateCatchEvent ,必須隻有一個入口順序流。

  • 圖示:
基于事件的網關,用内部帶有特殊圖示的網關(菱形)表示。
(二)BPMN2.0規範介紹——4網關 Gateways一、定義二、排他網關 Exclusive Gateway三、并行網關 Parallel Gateway四、包容網關 Inclusive Gateway五、基于事件的網關 Event­based Gateway
  • java代碼:
  •  xml表示:

用于定義基于事件的網關的XML元素為 eventBasedGateway 。

 下面的流程,是帶有基于事件的網關的流程的例子。當執行到達基于事件的網關時,流程執行被暫停。并且,流程執行個體訂閱alert信号事件,并建立一個 10分鐘後觸發的定時器。這使得流程引擎等待10分鐘,并等待信号事件。如果信号在10分鐘内觸發,則定時器會被取消,執行沿着信号繼續。如果信号未被觸 發,執行會在定時器到時後繼續,并取消信号訂閱。

(二)BPMN2.0規範介紹——4網關 Gateways一、定義二、排他網關 Exclusive Gateway三、并行網關 Parallel Gateway四、包容網關 Inclusive Gateway五、基于事件的網關 Event­based Gateway
<definitions id="definitions"
    xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
    xmlns:activiti="http://activiti.org/bpmn"
    targetNamespace="Examples">
<signal id="alertSignal" name="alert" />
    <process id="catchSignal">
        <startEvent id="start" />
        <sequenceFlow sourceRef="start" targetRef="gw1" />
        <eventBasedGateway id="gw1" />
        <sequenceFlow sourceRef="gw1" targetRef="signalEvent" />
        <sequenceFlow sourceRef="gw1" targetRef="timerEvent" />
        <intermediateCatchEvent id="signalEvent" name="Alert">
            <signalEventDefinition signalRef="alertSignal" />
        </intermediateCatchEvent>
        <intermediateCatchEvent id="timerEvent" name="Alert">
            <timerEventDefinition>
                <timeDuration>PT10M</timeDuration>
            </timerEventDefinition>
        </intermediateCatchEvent>
        <sequenceFlow sourceRef="timerEvent" targetRef="exGw1" />
        <sequenceFlow sourceRef="signalEvent" targetRef="task" />
        <userTask id="task" name="Handle alert"/>
        <exclusiveGateway id="exGw1" />
        <sequenceFlow sourceRef="task" targetRef="exGw1" />
        <sequenceFlow sourceRef="exGw1" targetRef="end" />
        <endEvent id="end" />
    </process>
</definitions>