Flowable中的各種網(wǎng)關(guān),你知道幾個?
網(wǎng)關(guān)
網(wǎng)關(guān)用來控制流程的流向。
1.排他網(wǎng)關(guān)
排他網(wǎng)關(guān)(exclusive gateway)(也叫異或網(wǎng)關(guān) XOR gateway,或者更專業(yè)的,基于數(shù)據(jù)的排他網(wǎng)關(guān) exclusive data-based gateway),用于對流程中的決策建模。當(dāng)執(zhí)行到達(dá)這個網(wǎng)關(guān)時,會按照所有出口順序流定義的順序?qū)λ鼈冞M(jìn)行計算。選擇第一個條件計算為true的順序流(當(dāng)沒有設(shè)置條件時,認(rèn)為順序流為true)繼續(xù)流程。
請注意這里出口順序流的含義與BPMN 2.0中的一般情況不一樣。一般情況下,會選擇所有條件計算為true的順序流,并行執(zhí)行。而使用排他網(wǎng)關(guān)時,只會選擇一條順序流。當(dāng)多條順序流的條件都計算為true時,會且僅會選擇在XML中最先定義的順序流繼續(xù)流程。如果沒有可選的順序流,會拋出異常。
排他網(wǎng)關(guān)用內(nèi)部帶有’X’圖標(biāo)的標(biāo)準(zhǔn)網(wǎng)關(guān)(菱形)表示,'X’圖標(biāo)代表異或的含義。請注意內(nèi)部沒有圖標(biāo)的網(wǎng)關(guān)默認(rèn)為排他網(wǎng)關(guān)。BPMN 2.0規(guī)范不允許在同一個流程中混合使用有及沒有X的菱形標(biāo)志。
案例:
/**
* 部署流程
*/
@Test
public void deploy(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
Deployment deploy = repositoryService.createDeployment()
.addClasspathResource("請假流程-排他網(wǎng)關(guān).bpmn20.xml")
.name("請求流程-排他網(wǎng)關(guān)")
.deploy();
System.out.println("deploy.getId() = " + deploy.getId());
System.out.println(deploy.getName());
}
/**
* 啟動流程實(shí)例
*/
@Test
public void runProcess(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
// 給流程定義中的UEL表達(dá)式賦值
Map<String,Object> variables = new HashMap<>();
// variables.put("g1","group1");
variables.put("num",3); // 給流程定義中的UEL表達(dá)式賦值
runtimeService.startProcessInstanceById("holiday-exclusive:1:4",variables);
}
/**
* 啟動流程實(shí)例
*/
@Test
public void setVariables(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
// 給流程定義中的UEL表達(dá)式賦值
Map<String,Object> variables = new HashMap<>();
// variables.put("g1","group1");
variables.put("num",4); // 給流程定義中的UEL表達(dá)式賦值
runtimeService.setVariables("12503",variables);
}
/**
* 完成任務(wù)
*/
@Test
public void completeTask(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
Task task = taskService.createTaskQuery()
//.processInstanceId("2501")
.processDefinitionId("holiday-exclusive:1:4")
.taskAssignee("zhangsan")
.singleResult();
if(task != null){
// 完成任務(wù)
taskService.complete(task.getId());
System.out.println("完成Task");
}
}
如果從網(wǎng)關(guān)出去的線所有條件都不滿足的情況下會拋出系統(tǒng)異常。
但是要注意任務(wù)沒有介紹,還是原來的任務(wù),我們可以重置流程變量。
@Test
public void setVariables(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
// 給流程定義中的UEL表達(dá)式賦值
Map<String,Object> variables = new HashMap<>();
// variables.put("g1","group1");
variables.put("num",4); // 給流程定義中的UEL表達(dá)式賦值
runtimeService.setVariables("12503",variables);
}
前面我們可以直接在連接線上定義條件,那為什么還要有排他網(wǎng)關(guān)呢?直接在線上的情況,如果條件都不滿足,流程就結(jié)束了,是異常結(jié)束!
2.并行網(wǎng)關(guān)
并行網(wǎng)關(guān)允許將流程分成多條分支,也可以把多條分支匯聚到一起,并行網(wǎng)關(guān)的功能是基于進(jìn)入和外出順序流的:
- fork分支:并行后的所有外出順序流,為每個順序流都創(chuàng)建一個并發(fā)分支。
- join匯聚: 所有到達(dá)并行網(wǎng)關(guān),在此等待的進(jìn)入分支, 直到所有進(jìn)入順序流的分支都到達(dá)以后, 流程就會通過匯聚網(wǎng)關(guān)。
注意,如果同一個并行網(wǎng)關(guān)有多個進(jìn)入和多個外出順序流, 它就同時具有分支和匯聚功能。 這時,網(wǎng)關(guān)會先匯聚所有進(jìn)入的順序流,然后再切分成多個并行分支。
與其他網(wǎng)關(guān)的主要區(qū)別是,并行網(wǎng)關(guān)不會解析條件。 即使順序流中定義了條件,也會被忽略。
案例:
當(dāng)我們執(zhí)行了創(chuàng)建請假單后,到并行網(wǎng)關(guān)的位置的時候,在ACT_RU_TASK表中就有兩條記錄。
然后同時在ACT_RU_EXECUTION中有三條記錄,一個任務(wù)對應(yīng)的有兩個執(zhí)行實(shí)例。
3.包含網(wǎng)關(guān)
包含網(wǎng)關(guān)可以看做是排他網(wǎng)關(guān)和并行網(wǎng)關(guān)的結(jié)合體。 和排他網(wǎng)關(guān)一樣,你可以在外出順序流上定義條件,包含網(wǎng)關(guān)會解析它們。 但是主要的區(qū)別是包含網(wǎng)關(guān)可以選擇多于一條順序流,這和并行網(wǎng)關(guān)一樣。
包含網(wǎng)關(guān)的功能是基于進(jìn)入和外出順序流的:
- 分支: 所有外出順序流的條件都會被解析,結(jié)果為true的順序流會以并行方式繼續(xù)執(zhí)行, 會為每個順序流創(chuàng)建一個分支。
- 匯聚:所有并行分支到達(dá)包含網(wǎng)關(guān),會進(jìn)入等待狀態(tài), 直到每個包含流程token的進(jìn)入順序流的分支都到達(dá)。 這是與并行網(wǎng)關(guān)的最大不同。換句話說,包含網(wǎng)關(guān)只會等待被選中執(zhí)行了的進(jìn)入順序流。 在匯聚之后,流程會穿過包含網(wǎng)關(guān)繼續(xù)執(zhí)行。
4.事件網(wǎng)關(guān)
事件網(wǎng)關(guān)允許根據(jù)事件判斷流向。網(wǎng)關(guān)的每個外出順序流都要連接到一個中間捕獲事件。 當(dāng)流程到達(dá)一個基于事件網(wǎng)關(guān),網(wǎng)關(guān)會進(jìn)入等待狀態(tài):會暫停執(zhí)行。與此同時,會為每個外出順序流創(chuàng)建相對的事件訂閱。
事件網(wǎng)關(guān)的外出順序流和普通順序流不同,這些順序流不會真的"執(zhí)行", 相反它們讓流程引擎去決定執(zhí)行到事件網(wǎng)關(guān)的流程需要訂閱哪些事件。 要考慮以下條件:
事件網(wǎng)關(guān)必須有兩條或以上外出順序流;
事件網(wǎng)關(guān)后,只能使用intermediateCatchEvent類型(activiti不支持基于事件網(wǎng)關(guān)后連接ReceiveTask);
連接到事件網(wǎng)關(guān)的中間捕獲事件必須只有一個入口順序流。