Activiti5需要jdk6以上的開發環境,Activiti6需要jdk7以上的開發環境,Activiti7支持雲,Activiti Cloud是第一個雲原生BPM框架,用於為雲環境中的BPM實現提供可伸縮和透明的解決方案。
Activiti6支持與spring和springboot的集成,默認數據庫是H2,可以支持mysql,oracle,db2,postgres,mssql等主流關系數據庫,本文主要講解基於springboot集成的activiti6的相關開發。
所需軟件版本
springBoot 2.0.1.RELEASE
activiti 6.0.0,
activiti-modeler-5.22.0-sources.jar
activiti-webapp-explorer2
5.1 在POM文件中添加依賴
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-basic</artifactId>
<version>6.0.0</version>
</dependency>
其他相關依賴見工程pom.xml
5.2 集成配置
activiti與springboot集成,相關配置可以通過yml文件或者配置類來實現,application.properties文件添加配置項。
spring.activiti.database-schema-update=true
databaseSchemaUpdate配置項可以設置流程引擎啟動和關閉時數據庫執行的策略。 databaseSchemaUpdate有以下四個值:
l false:false為默認值,設置為該值后,Activiti在啟動時,會對比數據庫表中保存的版本,如果沒有表或者版本不匹配時,將在啟動時拋出異常。
l true:設置為該值后,Activiti會對數據庫中所有的表進行更新,如果表不存在,則Activiti會自動創建。
l create-drop:Activiti啟動時,會執行數據庫表的創建操作,在Activiti關閉時,執行數據庫表的刪除操作。
l drop-create:Activiti啟動時,執行數據庫表的刪除操作在Activiti關閉時,會執行數據庫表的創建操作。
spring.activiti.history-level=full
對於歷史數據,保存到何種粒度,Activiti提供了history-level屬性對其進行配置。history-level屬性有點像log4j的日志輸出級別,該屬性有以下四個值:
l none:不保存任何的歷史數據,因此,在流程執行過程中,這是最高效的。
l activity:級別高於none,保存流程實例與流程行為,其他數據不保存。
l audit:除activity級別會保存的數據外,還會保存全部的流程任務及其屬性。audit為history的默認值。
l full:保存歷史數據的最高級別,除了會保存audit級別的數據外,還會保存其他全部流程相關的細節數據,包括一些流程參數等。
其他相關配置
syncExecutorEnabled屬性設置設置true后將代替那些老的Job executor
spring.activiti.async-executor-enabled=false
spring.activiti.job-executor-activate=false
asyncExecutorActivate是指示activiti在流程引擎啟動就激活AsyncExecutor,異步
spring.activiti.async-executor-activate=
校驗流程文件,默認校驗resources下的processes文件夾里的流程文件
spring.activiti.check-process-definitions=
使用自定義mybatis-mapper
spring.activiti.custom-mybatis-mappers=
spring.activiti.custom-mybatis-xmlmappers=
數據源指定
spring.activiti.database-schema=
建表規則
flase: 默認值。activiti在啟動時,會對比數據庫表中保存的版本,如果沒有表或者版本不匹配,將拋出異常。
true: activiti會對數據庫中所有表進行更新操作。如果表不存在,則自動創建。
create_drop: 在activiti啟動時創建表,在關閉時刪除表(必須手動關閉引擎,才能刪除表)。
drop-create: 在activiti啟動時刪除原來的舊表,然后在創建新表(不需要手動關閉引擎)
spring.activiti.database-schema-update=false
檢測歷史表是否存在
spring.activiti.db-history-used=false
檢測身份信息表是否存在
spring.activiti.db-identity-used=false
流程部署名稱
spring.activiti.deployment-name=
spring jpa使用
spring.activiti.jpa-enabled=false
郵件發送服務配置
spring.activiti.mail-server-default-from=
spring.activiti.mail-server-host=
spring.activiti.mail-server-password=
spring.activiti.mail-server-port=
spring.activiti.mail-server-use-ssl=
spring.activiti.mail-server-use-tls=
spring.activiti.mail-server-user-name=
自定義流程文件位置
spring.activiti.process-definition-location-prefix=
spring.activiti.process-definition-location-suffixes=
activiti rest 配置
spring.activiti.rest-api-enabled=false
spring.activiti.rest-api-mapping=
spring.activiti.rest-api-servlet-name=
5.3在線設計器拷貝項目資源
activiti6可以通過相關插件離線配置流程,也可以通過在線編輯配置流程。離線配置SpringBoot集成activiti默認會從classpath下的processes目錄下讀取流程定義文件,所以需要在src/main/resources目錄下添加processes目錄,並在目錄中創建流程文件。
在線配置流程,通過如下方法:
解壓activiti-webapp-explorer2,把webapp下面的diagram-viewer、editor-app、modeler.html復制到springboot項目下的static下,這是activiti的在線設計器,modeler.html就是設計的主界面,復制resources下stencilset.json到自己的resources下。
解壓activiti-5.23.0的包,將libs下的activiti-modeler-5.23.0-sources.jar解壓出來,把org\activiti\rest\editor路徑下的main、model文件夾復制到springboot項目的源碼路徑下,里面有三個類,主要用於讀取stencilset.json。
5.4修改拷貝過來的資源文件
修改如下3個controller,加上@RequestMapping("/service")
StencilsetRestResource.java
ModelEditorJsonRestResource.java
ModelSaveRestResource.java
修改editor-app下的app-cfg.js,把contextRoot后面改成 /service,和controller里面加的requestMapping要一致
5.5 用戶信息及組整合
Activiti 中的用戶與組用於界定任務的候選者與辦理者。組可以理解為角色,屬於某個組的用戶,就可以作為某個任務的候選者或者辦理者。我們還可以通過 Activiti 的 API 來創建、查詢或刪除某個用戶或者某個組。Activiti 還提供了建立關系的 API 用於綁定用戶與組之間的關系。如下圖是用戶與用戶組相關的數據庫表
在 Activiti 中,組的類型分為 assignment 和 security-role ,前者是普通角色,用於分配業務功能權限;后者是管理角色,用於管理組織結構與流程。用戶與組之間的關系是多對多。一個用戶可以歸屬於多個組;而一個組也可以包含多個用戶。
需要說明的是,Activiti 用戶和組也可以不整合,用業務系統中的用戶角色數據庫表。但是需要按照activiti接口規范提供用戶角色相關的接口。如下圖,對用戶節點選擇代理時,需要選擇用戶或者候選用戶組(角色)。
如角色接口Get請求
http://localhost/sys/role/page?token=null&page=1&limit=20
用戶接口get請求
http://localhost/sys/user/page?token=null&page=1&limit=20
5.6 配置模型
如下圖,流程圖需要完整的開始、結束節點,除此之外,需要有用戶節點,如果有互斥網關,需要指定分支流轉條件,中間節點需要有輸入,輸出,且輸入輸出箭頭需要指定具體的節點,不能出現箭頭指向為空。如果有子流程,子流程中也需要有完整的開始,結束節點。
配置代理人,用戶和組可以指定具體人,動態配置可以用${xxx}來表示。如${auditUserId},用戶提交時,就需要傳遞auditUserId參數變量。
5.7 多實例模型配置說明
多實例可以配置在各種類型的任務節點、子流程、回調活動節點上。下圖紅色方框是涉及多實例需要配置的字段:
A.多實例包含的默認變量
多實例包含的默認變量,可以通過execution.getVariable(x)方法獲取:
nrOfInstances:創建的實例總數;
nrOfActiveInstances:當前活動的實例數,針對順序類型的多實例,該變量值等於1;
nrOfCompletedInstances:已執行實例數;
loopCounter:表示多實例流程循環的下標。
基於如上變量,可以設置多實例任務的流轉條件。如需要2/3通過,就可以設置流轉條件為${nrOfCompletedInstances/nrOfInstances==2/3}。如下圖:
B.多實例類型
順序(sequential ):按順序出實例,當前活動實例數(nrOfActiveInstances)一直是1
並行(parallel):多個實例會同時並行發放給處理人。
C.基數(多實例)
定義多實例生成的實例數。當結合采集方式生成多實例時,該基數只能小於或等於采集集合的size,否則執行過程中將發生系統錯誤 NoSuchElementException;當基數小於采集集合的size時,則按照集合中元素的順序生成等於基數指定數量的實例。如果不配合使用采集方式,也可以直接指定基數,則系統會同時生成指定數量的相同實例。
D.采集(多實例)/集合(多實例)
用於指定一個List,自動生成等於List size數量的實例。可以將該List設置為處理人員列表,然后設置元素變量名,並將分配—固定值—處理人/代理人設置為元素變量名,則最后會為每一個集合中的人員生成一個已指派實例。
E.元素變量(多實例)
表示多實例采集中元素對應的變量,該變量保存着集合中元素的最新值,可以使用表達式獲取。
F.完成條件(多實例)
是一個表達式,如果返回值為true則該多實例自動結束。例如 ${nrOfCompletedInstances/nrOfInstances >= 0.6 } 只要所有流程實例完成了60%即該多實例任務結束。
G.分配/代理
在使用多實例的情況下,當將分配—固定值—處理人/代理人/候選人設置為多實例元素變量名時,則生成的實例會對應自動指派給列表中配置的處理人。
5.8 配置並行多實例用戶任務模型舉例
在很多情況下,我們需要多用戶共同執行余下流程,比如開會流程:領導發起開會,選擇開會人員(多個),每個開會人員接收到通知后需要簽到(一名用戶簽到不會影響到另一位用戶的簽到),簽到完成后則流程結束。此時,就需要用到多實例(多任務)。
A.創建模型
B.領導發起開會
由於具體是哪個領導發起開會有不確定性(只要是領導都可以發起),所以需要設置代理人屬性:Assignee: ${leader} 。
為了方便后面的【開發人員簽到】流程,我們還需要在【領導發起開會】流程處設置一個流程執行監聽器(此操作不是必須,此處只是為了解釋動態多實例),在Activiti中,配置監聽器需要在模型和JAVA中都進行相應配置:在JAVA中我們想要創建監聽器只需要創建一個類,並實現系統監聽器類 ExecutionListener 即可,代碼如下:
接下來就是模型中的配置,由於我們想在領導指派了開會人員后進行監聽,所以需要如下設置
其中 Event 代表事件觸發類型,作用如其名Class 代表監聽器全路徑,此處為 com.kenary.activiti.listener.MyExecutionListener,則是之前創建的 MyExecutionListener。監聽器配置完成后領導發起開會流程就配置完成。
C.開會人員簽到
相對於領導發起開會流程,開發人員簽到流程則需要配置更多內容。
其中,集合(Collection)設置的是存儲開會人員集合的變量名,注意:此處不需要${},並且 變量的值必須是 Collection的子類,即List、Set等。
多實例類型設置的是並行、串行等方式。並行代表同時進行,如把任務分給5個人來處理,這5個人同時會收到任務,並且可以同時處理,不受各自的影響。串行代表工作或任務由一個人完成后,再由另一個人去處理,直至全部完成,每個任務依賴於前一個任務完成。
元素變量(Element variable) 設置的是集合(Collection)每遍歷一次設置的變量值的變量名,即迭代集合時存儲集合里面單個元素的變量名,集合遍歷時會根據內容創建任務。
代理設置的是處理該任務的用戶,由於集合每遍歷一次就創建了一個任務,所以這里和領導發起開會流程無太大差異,指定代理人即可,不過代理人員需要使用元素變量(Element variable)(Item 迭代的值)。
流程配置后,需要保存。