Docker 的優點
1370
2025-03-31
BPMN 2.0介紹
業務流程模型注解(BusinessProcess Modeling Notation - BPMN)是業務流程模型的一種標準圖形注解.這個標準是由對象管理組(Object Management Group - OMG)維護的
BPMN規范的2.0版本允許添加精確的技術細節在BPMN的圖形和元素中,同時制定BPMN元素的執行語法.通過使用XML語言來指定業務流程的可執行語法,BPMN規范已經演變為業務流程的語言,可以執行在任何兼容BPMN2的流程引擎中,同時依然可以使用強大的圖形注解
簡單來說,BPMN即圖標與標簽的結合
定義一個流程
創建一個新的XML文件并命名,確認文件后綴為 .bpmn20.xml或 .bpmn, 否則引擎無法發布
BPMN 2.0根節點是definitions節點. 這個元素中,可以定義多個流程定義(不過建議每個文件只包含一個流程定義, 可以簡化開發過程中的維護難度)
一個空的流程定義如下所示:注意definitions元素最少也要包含xmlns和 targetNamespace的聲明
targetNamespace可以是任意值,它用來對流程實例進行分類
可以選擇添加線上的BPMN 2.0格式位置:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL http://www.omg.org/spec/BPMN/2.0/20100501/BPMN20.xsd
==process元素有兩個屬性:==
id: 這個屬性是必須的,對應著Activiti ProcessDefinition對象的key屬性.id可以用來啟動流程定義的流程實例,通過RuntimeService的startProcessInstanceByKey方法
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myProcess");
==注意:== 它和startProcessInstanceById方法不同:這個方法期望使用Activiti引擎在發布時自動生成的id.可以通過調用processDefinition.getId() 方法獲得這個值,生成的id的格式為 key:version, 最大長度限制為64個字符, 如果在啟動時拋出了一個ActivitiException: 說明生成的id太長了,需要限制流程的key的長度
name: 這個屬性是可選的, 對應ProcessDefinition的name屬性.引擎自己不會使用這個屬性,是用來在用戶接口顯示便于閱讀的名稱
BPMN流程示例前提
已經安裝Activiti并且能夠運行Activiti Demo
使用了獨立運行的H2服務器
修改db.properties,設置其中的jdbc.url=jdbc:h2:tcp://localhost/activiti,然后啟動獨立服務器
目標
學習Activiti和一些基本的BPMN 2.0概念
最終結果是一個簡單的Java SE程序可以發布流程定義,通過Activiti引擎API操作流程
使用一些Activiti相關的工具,構建自己的業務流程web應用
用例
每個月都要給公司領導一個金融報表,由會計部門負責
當報表完成時,一個上級領導需要審批文檔,然后才能發給所有領導
流程圖
流程的圖形化BPMN 2.0標記:
空開始事件(左側圓圈),后面是兩個用戶任務:制作月度財報和驗證月度財報,最后是空結束事件(右側粗線圓圈)
XML內容
在業務流程的XML中很容易找到流程的主要元素:
(空)開始事件是流程的入口
第一個任務分配給accountancy組
第二個任務分配給management組
當流程達到空結束事件就會結束
這些元素都使用連線連接,這些連線擁有source和target屬性,定義了連線的方向
啟動一個流程實例
創建好業務流程的流程定義,就可以創建流程實例
一個流程實例對應了特定月度財報的創建和審批,所有流程實例都共享同一個流程定義
為了使用流程定義創建流程實例,首先要發布業務流程:
流程定義會保存到持久化的數據存儲里,是為Activiti引擎特別配置的.所以部署好業務流程,在引擎重啟后還能找到流程定義
BPMN 2.0流程文件會解析成內存對象模型, 可以通過Activiti API操作
通過下面的API發布流程,所有與Activiti引擎的交互都是通過services
Deployment deployment = repositoryService.createDeployment() .addClasspathResource("FinancialReportProcess.bpmn20.xml") .deploy();
啟動一個新流程實例,使用我們定義在流程定義里的id(對應XML文件中的process元素).==注意這里的id對于Activiti來說,應該叫做key==,一般在流程模型中使用的ID,在Activiti中都是Key:比如任務ID
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("financialReport");
這樣創建一個流程實例:
首先進入開始事件
開始事件之后,它會沿著所有的外出連線執行,到達第一個任務(“制作月度財報”)
Activiti會把一個任務保存到數據庫里.這時,分配到這個任務的用戶或群組會被解析,也會保存到數據庫里
需要注意,Activiti引擎會繼續執行流程的環節,除非遇到一個 等待狀態:比如用戶任務
在等待狀態下,當前的流程實例的狀態會保存到數據庫中.直到用戶決定完成任務才能改變這個狀態
這時,引擎會繼續執行,直到遇到下一個等待狀態,或流程結束
如果中間引擎重啟或崩潰,流程狀態也會安全的保存在數據庫里
任務創建之后,startProcessInstanceByKey會在到達用戶任務這個等待狀態之后才會返回.這時,任務分配給了一個組,這意味著這個組是執行這個任務的候選組
現在將所有東西都放在一起,來創建一個簡單的java程序:
創建一個Java項目,把Activiti的jar和依賴放到classpath下:這些都可以在Activiti發布包的libs目錄下找到
在調用Activiti服務之前,我們必須構造一個ProcessEngine,可以讓我們訪問服務
這里我們使用[單獨運行]的配置,這會使用demo安裝時的數據庫來構建ProcessEngine
public static void main(String[] args) { // Create Activiti process engine ProcessEngine processEngine = ProcessEngineConfiguration .createStandaloneProcessEngineConfiguration() .buildProcessEngine(); // Get Activiti services RepositoryService repositoryService = processEngine.getRepositoryService(); RuntimeService runtimeService = processEngine.getRuntimeService(); // Deploy the process definition repositoryService.createDeployment() .addClasspathResource("FinancialReportProcess.bpmn20.xml") .deploy(); // Start a process instance runtimeService.startProcessInstanceByKey("financialReport"); }
任務列表
可以通過TaskService來獲得任務,添加以下邏輯:
List
注意傳入的用戶必須是accountancy組的一個成員,要和流程定義中相對應:
也可以使用群組名稱,通過任務查詢API來獲得相關的結果.在代碼中添加如下邏輯:
TaskService taskService = processEngine.getTaskService(); List
因為配置的ProcessEngine使用了與demo相同的數據,可以登錄到Activiti Explorer.默認,accountancy(會計)組里沒有任何人:
登錄
點擊組
創建一個新組
點擊用戶
把組分配給fozzie
使用fozzie/fozzie登錄
就可以啟動我們的業務流程了,選擇Processes頁,在[月度財報]的[操作]列點擊[啟動流程]
流程會執行到第一個用戶任務.因為我們以kermit登錄,在啟動流程實例之后,就可以看到有了一個新的待領任務.選擇任務頁來查看這條新任務.注意即使流程被其他人啟動,任務還是會被會計組里的所有人作為一個候選任務看到
領取任務
現在一個會計要認領這個任務
認領以后,這個用戶就會成為任務的執行人,任務會從會計組的其他成員的任務列表中消失.認領任務的代碼:
taskService.claim(task.getId(), "fozzie");
任務會進入認領任務人的個人任務列表:
List
在Activiti Explorer UI中,點擊認領按鈕,會執行相同的操作.任務會移動到登錄用戶的個人任務列表.你也會看到任務的執行人已經變成當前登陸的用戶:
完成任務
現在會計可以開始進行財報的工作
報告完成后,他可以完成任務,意味著任務所需的所有工作都完成
taskService.complete(task.getId());
對于Activiti引擎:
需要一個外部信息來讓流程實例繼續執行
任務會把自己從運行庫中刪除
流程會沿著單獨一個外出連線執行,移動到第二個任務(審批報告)
與第一個任務相同的機制會使用到第二個任務上,不同的是任務是分配給management組
在demo中:
完成任務是通過點擊任務列表中的完成按鈕
因為Fozzie不是會計,我們先從Activiti Explorer注銷
然后使用kermit登陸(經理),第二個任務會進入未分配任務列表
結束流程
審批任務像之前一樣查詢和領取.
完成第二個任務會讓流程執行到結束事件,就會結束流程實例
流程實例和所有相關的運行數據都會從數據庫中刪除
登錄Activiti Explorer就可以進行驗證,可以看到保存流程運行數據的表中已經沒有數據:
可以使用historyService判斷流程是否已經結束:
HistoryService historyService = processEngine.getHistoryService(); HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(procId).singleResult(); System.out.println("Process instance end time: " + historicProcessInstance.getEndTime());
源碼
考慮到你可能會在Activiti Explorer UI中啟動一些流程實例,這樣,它會獲得多個任務,而不是一個,所以代碼可以一直正常運行:
public class TenMinuteTutorial { public static void main(String[] args) { // Create Activiti process engine ProcessEngine processEngine = ProcessEngineConfiguration .createStandaloneProcessEngineConfiguration() .buildProcessEngine(); // Get Activiti services RepositoryService repositoryService = processEngine.getRepositoryService(); RuntimeService runtimeService = processEngine.getRuntimeService(); // Deploy the process definition repositoryService.createDeployment() .addClasspathResource("FinancialReportProcess.bpmn20.xml") .deploy(); // Start a process instance String procId = runtimeService.startProcessInstanceByKey("financialReport").getId(); // Get the first task TaskService taskService = processEngine.getTaskService(); List
總結
可以通過Activiti中的BPMN 2.0結構,對業務流程進行以下方面的:
定義網關來實現決策環節: 經理可以駁回財報,重新給會計創建一個任務
考慮使用變量: 可以保存或引用報告,把它顯示到表單中
在流程最后加入服務任務: 把報告發給每個領導
XML 數據庫
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。