activiti入門3排他網關,並行網管,包括網關,事件網關
網關用來控制流程的流向 網關能夠消費也能夠生成token。
網關顯示成菱形圖形,內部有有一個小圖標。 圖標表示網關的類型。
基本分支
首先 利用 流程變量 寫個帶有分支的一個基本流程
流程圖:
部署流程文件:
//獲取流程引擎 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); @Test public void deployFlow(){ //獲取倉庫服務對象 RepositoryService repositoryService = processEngine.getRepositoryService(); InputStream in = this.getClass().getResourceAsStream("/MyProcess11.zip"); ZipInputStream zipInputStream = new ZipInputStream(in); Deployment dm = repositoryService.createDeployment() .name("學生請假") .addZipInputStream(zipInputStream) .deploy(); System.out.println("id:"+dm.getId()+",name:"+dm.getName()); }
/** * 啟動流程 並完畢 提交 */ @Test public void startProcessAndComp(){ RuntimeService runtimeService = processEngine.getRuntimeService(); ProcessInstance pi = runtimeService.startProcessInstanceByKey("leave"); System.out.println("id:"+pi.getId()+",流程實例ID:"+pi.getProcessInstanceId()+",流程定義ID:"+pi.getProcessDefinitionId()); TaskService taskService = processEngine.getTaskService(); //通過流程實例ID獲取任務對象 Task task = taskService.createTaskQuery() .processInstanceId(pi.getProcessInstanceId()) .singleResult(); System.out.println("taskID:"+task.getId()+",name:"+task.getName()); Map<String, Object> paramMap = new HashMap<String, Object>(); //設置流程變量day=3 paramMap.put("day", 3); //提交任務的時候傳入流程變量 taskService.complete(task.getId(), paramMap); //查詢任務 task = taskService.createTaskQuery() .processInstanceId(pi.getProcessInstanceId()) .singleResult(); //假設任務對象為空,則流程運行結束 if (task != null) { System.out.println("taskID:"+task.getId()+",name:"+task.getName()); } else { System.out.println("任務運行完畢"); } }
最後的執行結果:
id:1501,流程實例ID:1501,流程定義ID:leave:2:1404 taskID:1504,name:班主任 任務運行完成
我們能夠再數據庫中查看:
我們再部署一個 流程文件 , 而且在提交 任務的時候 設置流程變量 請假天數為 10天
最後的執行結果
id:1701,流程實例ID:1701,流程定義ID:leave:3:1604 taskID:1704,name:班主任 taskID:1707,name:年級主任
如今 流程就到了另外 一條線
年紀主任審批通過:
/** * 提交任務 */ @Test public void completeTask(){ TaskService taskService = processEngine.getTaskService(); taskService.complete("1707"); }
流程運行結束
排他網關:
排他網關描寫敘述
排他網關(也叫異或(XOR)網關,或更技術性的叫法 基於數據的排他網關), 用來在流程中實現決策。 當流程運行到這個網關,全部外出順序流都會被處理一遍。 當中條件解析為true的順序流(或者沒有設置條件,概念上在順序流上定義了一個‘true‘) 會被選中,讓流程繼續執行。
註意這裏的外出順序流 與BPMN 2.0通常的概念是不同的。
通常情況下,全部條件結果為true的順序流 都會被選中。以並行方式運行。但排他網關僅僅會選擇一條順序流運行。 就是說,盡管多個順序流的條件結果為true。 那麽XML中的第一個順序流(也僅僅有這一條)會被選中,並用來繼續運行流程。
假設沒有選中不論什麽順序流。會拋出一個異常。
排他網關圖形
排他網關顯示成一個普通網關(比方。菱形圖形), 內部是一個“X”圖標,表示異或(XOR)語義。
註意。沒有內部圖標的網關,默覺得排他網關。 BPMN 2.0規範不同意在同一個流程定義中同一時候使用沒有X和有X的菱形圖形。
流程文件:
排他網關有個默認的選項 default flow , 當 default flow 設定後 就不用設置表達式了, 假設全部的條件都不通過 就會運行默認的流程
年級主任審批和校長審批
首先 還是 先把文件部署
//獲取流程引擎 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); @Test public void deployFlow2(){ //獲取倉庫服務對象 RepositoryService repositoryService = processEngine.getRepositoryService(); InputStream in = this.getClass().getResourceAsStream("/exclusiveGateway.zip"); ZipInputStream zipInputStream = new ZipInputStream(in); Deployment dm = repositoryService.createDeployment() .name("學生請假") .addZipInputStream(zipInputStream) .deploy(); System.out.println("id:"+dm.getId()+",name:"+dm.getName()); }
id:2001,流程實例ID:2001,流程定義ID:exclusiveGateWay:1:1904 taskID:2004,name:學生請假 taskID:2008,name:年級主任審批
再 又一次部署一個流程文件 然後啟動 提交 設置請假天數為 30天 運行結果
id:2201,name:學生請假
id:2301,流程實例ID:2301,流程定義ID:exclusiveGateWay:2:2204 taskID:2304,name:學生請假 taskID:2308,name:校長審批最後在 部署一遍, 這次設置請假天數為 3天 結果
id:2501,name:學生請假
id:2601,流程實例ID:2601,流程定義ID:exclusiveGateWay:3:2504 taskID:2604,name:學生請假 taskID:2608,name:班主任審批
這裏 流程走到了 當初 默認的設置 班主任審批
當我們設置了 默認 的 配置 ,即使沒有 設置表達式 流程 條件都 不滿足的時候 都會運行默認的
並行網關
並行網關描寫敘述
網關也能夠表示流程中的並行情況。最簡單的並行網關是 並行網關,它同意將流程 分成多條分支。也能夠把多條分支 匯聚到一起。 of execution.
並行網關的功能是基於進入和外出的順序流的:
-
分支: 並行後的全部外出順序流,為每一個順序流都創建一個並發分支。
-
匯聚: 全部到達並行網關。在此等待的進入分支。 直到全部進入順序流的分支都到達以後。 流程就會通過匯聚網關。
註意。假設同一個並行網關有多個進入和多個外出順序流。 它就同一時候具有分支和匯聚功能。 這時。網關會先匯聚全部進入的順序流,然後再切分成多個並行分支。
與其它網關的主要差別是,並行網關不會解析條件。
即使順序流中定義了條件。也會被忽略。
並行網關圖形
並行網關顯示成一個普通網關(菱形)內部是一個“加號”圖標, 表示“與(AND)”語義。
首先 畫一個簡單的並行流程
註意 並行 網關 要有2個 一個是用於 分支 一個用於 聚合
部署啟動@Test public void deployFlow3() { // 獲取倉庫服務對象 RepositoryService repositoryService = processEngine .getRepositoryService(); InputStream in = this.getClass().getResourceAsStream("/Parallel.zip"); ZipInputStream zipInputStream = new ZipInputStream(in); Deployment dm = repositoryService.createDeployment().name("並行網關") .addZipInputStream(zipInputStream).deploy(); System.out.println("id:" + dm.getId() + ",name:" + dm.getName()); RuntimeService runtimeService = processEngine.getRuntimeService(); ProcessInstance pi = runtimeService .startProcessInstanceByKey("parallel"); System.out.println("id:" + pi.getId() + ",流程實例ID:" + pi.getProcessInstanceId() + ",流程定義ID:" + pi.getProcessDefinitionId()); }
id:2801,name:並行網關
id:2901,流程實例ID:2901,流程定義ID:parallel:1:2804此時流程進入 啟動項目環節 通過流程實例ID 查看當前流程 進度
/** * 啟動流程 並完畢 提交 */ @Test public void startProcessAndComp3() { TaskService taskService = processEngine.getTaskService(); // 查詢任務 Task task = taskService.createTaskQuery().processInstanceId("2901").singleResult(); // 假設任務對象為空,則流程運行結束 if (task != null) { System.out.println("taskID:" + task.getId() + ",name:" + task.getName()); } else { System.out.println("任務運行完畢"); } // 通過流程實例ID獲取任務對象 task = taskService.createTaskQuery().processInstanceId("2901").singleResult(); System.out.println("taskID:" + task.getId() + ",name:" + task.getName()); // 提交任務 taskService.complete(task.getId()); }
taskID:2904,name:項目啟動 taskID:2904,name:項目啟動提交任務後,流程進入並行環節,同一時候運行 功能模塊1 和 功能模塊2
這是我們能夠看到 流程實例ID 和 運行對象ID 已經是不同了
這個是 act_ru_execution 表的數據
我們先 提交一個 功能模塊1的任務
在看 任務表 act_ru_task
此時 任務表 僅僅有 功能模塊2
我們在看 act_ru_execution 這個表 依然是3條數據 功能模塊1 的運行流程 被堵塞在 並行網關這裏 沒有進入 測試公布這個 環節
在提交功能模塊2 任務
查看 這 2個表
流程 已經 進入 下一個環節
提交最後一個人 整個流程結束, 我們在查看 歷史活動表 act_hi_actinst
整個流程 分成了 2 塊
包括網關
包括網關描寫敘述
包括網關能夠看做是排他網關和並行網關的結合體。 和排他網關一樣,你能夠在外出順序流上定義條件。包括網關會解析它們。 可是基本的差別是包括網關能夠選擇多於一條順序流。這和並行網關一樣。
包括網關的功能是基於進入和外出順序流的:
-
分支: 全部外出順序流的條件都會被解析。結果為true的順序流會以並行方式繼續運行。 會為每一個順序流創建一個分支。
-
匯聚: 全部並行分支到達包括網關。會進入等待章臺, 直到每一個包括流程token的進入順序流的分支都到達。 這是與並行網關的最大不同。換句話說,包括網關僅僅會等待被選中運行了的進入順序流。 在匯聚之後,流程會穿過包括網關繼續運行。
註意,假設同一個包括節點擁有多個進入和外出順序流。 它就會同一時候含有分支和匯聚功能。
這時,網關會先匯聚全部擁有流程token的進入順序流。 再依據條件推斷結果為true的外出順序流,為它們生成多條並行分支。
包括網關圖形
並行網關顯示為一個普通網關(菱形),內部包括一個圓圈圖標。
當 main config 中的 表達式 條件返回的結果為真時 運行 並行網關
結果為假時 運行 排他任務
詳細的 流程 這裏就不介紹了
事件網關
事件網關描寫敘述
基於事件網關同意依據事件推斷流向。
網關的每一個外出順序流都要連接到一個中間捕獲事件。 當流程到達一個基於事件網關,網關會進入等待狀態:會暫停運行。 與此同一時候,會為每一個外出順序流創建相對的事件訂閱。
註意基於事件網關的外出順序流和普通順序流不同。這些順序流不會真的"運行"。
相反。它們讓流程引擎去決定運行到基於事件網關的流程須要訂閱哪些事件。
要考慮下面條件:
-
基於事件網關必須有兩條或以上外出順序流。
-
基於事件網關後,僅僅能使用
intermediateCatchEvent
類型。 (activiti不支持基於事件網關後連接ReceiveTask。) -
連接到基於事件網關的
intermediateCatchEvent
僅僅能有一條進入順序流。
事件網關圖形
事件網關和其它BPMN網關一樣顯示成一個菱形, 內部包括指定圖標。
這裏 事件 太多了 就 先到這裏 0.0
activiti入門3排他網關,並行網管,包括網關,事件網關