工作流引擎 Activiti 保姆級教程
一、工作流介紹
1.1 概念
工作流(Workflow),就是透過計算機對業務流程自動化執行管理。它主要解決的是“使在多個參與者之間按照某種預定義的規則自動進行傳遞文件、資訊或任務的過程,從而實現某個預期的業務目標,或者促使此目標的實現”。
1.2 工作流系統
一個軟體系統中具有工作流的功能,我們把它稱為工作流系統,一個系統中工作流的功能是什麼?就是對系統的業務流程進行自動化管理,所以工作流是建立在業務流程的基礎上,所以一個軟體的系統核心根本上還是系統的業務流程,工作流只是協助進行業務流程管理。即使沒有工作流業務系統也可以開發執行,只不過有了工作流可以更好的管理業務流程,提高系統的可擴充套件性。
1.3 適用行業
消費品行業,製造業,電信服務業,銀證險等金融服務業,物流服務業,物業服務業,物業管理,大中型進出口貿易公司,政府事業機構,研究院所及教育服務業等,特別是大的跨國企業和集團公司。
1.4 具體應用
1、關鍵業務流程:
訂單、報價處理、合同稽核、客戶電話處理、供應鏈管理等
2、行政管理類:
出差申請、加班申請、請假申請、用車申請、各種辦公用品申請、購買申請、日報週報等凡是原來手工流轉處理的行政表單。
3、人事管理類:
員工培訓安排、績效考評、職位變動處理、員工檔案資訊管理等。
4、財務相關類:
付款請求、應收款處理、日常報銷處理、出差報銷、預算和計劃申請等。
5、客戶服務類:
客戶資訊管理、客戶投訴、請求處理、售後服務管理等。
6、特殊服務類:
ISO系列對應流程、質量管理對應流程、產品資料資訊管理、貿易公司報關處理、物流公司貨物跟蹤處理等各種透過表單逐步手工流轉完成的任務均可應用工作流軟體自動規範地實施。
1.5 實現方式
在沒有專門的工作流引擎之前,我們之前為了實現流程控制,通常的做法就是採用狀態欄位的值來跟蹤流程的變化情況。這樣不同角色的使用者,透過狀態欄位的取值來決定記錄是否顯示。
針對有許可權可以檢視的記錄,當前使用者根據自己的角色來決定審批是否合格的操作。如果合格將狀態欄位設定一個值,來代表合格;當然如果不合格也需要設定一個值來代表不合格的情況。
這是一種最為原始的方式。透過狀態欄位雖然做到了流程控制,但是當我們的流程發生變更的時候,這種方式所編寫的程式碼也要進行調整。
那麼有沒有專業的方式來實現工作流的管理呢?並且可以做到業務流程變化之後,我們的程式可以不用改變,如果可以實現這樣的效果,那麼我們的業務系統的適應能力就得到了極大提升。
二、Activiti7概述
2.1 介紹
Alfresco軟體在2010年5月17日宣佈Activiti業務流程管理(BPM)開源專案的正式啟動,其首席架構師由業務流程管理BPM的專家 Tom Baeyens擔任,Tom Baeyens就是原來jbpm的架構師,而jbpm是一個非常有名的工作流引擎,當然activiti也是一個工作流引擎。
Activiti是一個工作流引擎, activiti可以將業務系統中複雜的業務流程抽取出來,使用專門的建模語言BPMN2。0進行定義,業務流程按照預先定義的流程進行執行,實現了系統的流程由activiti進行管理,減少業務系統由於流程變更進行系統升級改造的工作量,從而提高系統的健壯性,同時也減少了系統開發維護成本。
官方網站:
https://www。
activiti。org/
經歷的版本:
目前最新版本:Activiti7。0。0。Beta
2.1.1 BPM
BPM(Business Process Management),即業務流程管理,是一種規範化的構造端到端的業務流程,以持續的提高組織業務效率。常見商業管理教育如EMBA、MBA等均將BPM包含在內。
2.1.2 BPM軟體
BPM軟體就是根據企業中業務環境的變化,推進人與人之間、人與系統之間以及系統與系統之間的整合及調整的經營方法與解決方案的IT工具。
透過BPM軟體對企業內部及外部的業務流程的整個生命週期進行建模、自動化、管理監控和最佳化,使企業成本降低,利潤得以大幅提升。
BPM軟體在企業中應用領域廣泛,凡是有業務流程的地方都可以BPM軟體進行管理,比如企業人事辦公管理、採購流程管理、公文審批流程管理、財務管理等。
2.1.3 BPMN
BPMN(Business Process Model AndNotation)- 業務流程模型和符號 是由BPMI(BusinessProcess Management Initiative)開發的一套標準的業務流程建模符號,使用BPMN提供的符號可以建立業務流程。
2004年5月釋出了BPMN1。0規範。BPMI於2005年9月併入OMG(The Object Management Group物件管理組織)組織。OMG於2011年1月釋出BPMN2。0的最終版本。
具體發展歷史如下:
BPMN 是目前被各 BPM 廠商廣泛接受的 BPM 標準。Activiti 就是使用 BPMN 2。0 進行流程建模、流程執行管理,它包括很多的建模符號,比如:Event
用一個圓圈表示,它是流程中執行過程中發生的事情。
活動用圓角矩形表示,一個流程由一個活動或多個活動組成
Bpmn圖形其實是透過xml表示業務流程,上邊的。bpmn檔案使用文字編輯器開啟:
<?xml version=“1。0” encoding=“UTF-8”?>
2.2 使用步驟
部署activiti
Activiti是一個工作流引擎(其實就是一堆jar包API),業務系統訪問(操作)activiti的介面,就可以方便的操作流程相關資料,這樣就可以把工作流環境與業務系統的環境整合在一起。
流程定義
使用activiti流程建模工具(activity-designer)定義業務流程(。bpmn檔案) 。
。bpmn檔案就是業務流程定義檔案,透過xml定義業務流程。
流程定義部署
activiti部署業務流程定義(。bpmn檔案)。
使用activiti提供的api把流程定義內容儲存起來,在Activiti執行過程中可以查詢定義的內容
Activiti執行把流程定義內容儲存在資料庫中
啟動一個流程例項
流程例項也叫:ProcessInstance
啟動一個流程例項表示開始一次業務流程的執行。
在員工請假流程定義部署完成後,如果張三要請假就可以啟動一個流程例項,如果李四要請假也啟動一個流程例項,兩個流程的執行互相不影響。
使用者查詢待辦任務(Task)
因為現在系統的業務流程已經交給activiti管理,透過activiti就可以查詢當前流程執行到哪了,當前使用者需要辦理什麼任務了,這些activiti幫我們管理了,而不需要開發人員自己編寫在sql語句查詢。
使用者辦理任務
使用者查詢待辦任務後,就可以辦理某個任務,如果這個任務辦理完成還需要其它使用者辦理,比如採購單建立後由部門經理稽核,這個過程也是由activiti幫我們完成了。
流程結束
當任務辦理完成沒有下一個任務結點了,這個流程例項就完成了。
三、Activiti環境
3.1 開發環境
Jdk1。8或以上版本
Mysql 5及以上的版本
Tomcat8。5
IDEA
注意:activiti的流程定義工具外掛可以安裝在IDEA下,也可以安裝在Eclipse工具下
3.2 Activiti環境
我們使用:
Activiti7。0。0。Beta1
預設支援spring5
3.2.1 下載activiti7
Activiti下載地址:
http://activiti。org/download。html
,Maven的依賴如下:
1) Database:
activiti執行需要有資料庫的支援,支援的資料庫有:h2, mysql, oracle, postgres, mssql, db2。
3.2.2 流程設計器IDEA下安裝
在IDEA的File選單中找到子選單”Settings”,後面我們再選擇左側的“plugins”選單,如下圖所示:
此時我們就可以搜尋到actiBPM外掛,它就是
Activiti Designer
的IDEA版本,我們點選Install安裝。
安裝好後,頁面如下:
提示需要重啟idea,點選重啟。
重啟完成後,再次開啟Settings 下的 Plugins(外掛列表),點選右側的Installed(已安裝的外掛),在列表中看到actiBPM,就說明已經安裝成功了,如下圖所示:
後面的課程裡,我們會使用這個流程設計器進行Activiti的流程設計。
3.3 Activiti的資料庫支援
Activiti 在執行時需要資料庫的支援,使用25張表,把流程定義節點內容讀取到資料庫表中,以供後續使用。
3.3.1 Activiti 支援的資料庫
activiti 支援的資料庫和版本如下:
3.3.2 在MySQL生成表
3.3.2.1 建立資料庫
建立 mysql 資料庫 activiti (名字任意):
CREATE DATABASE activiti DEFAULT CHARACTER SET utf8;
3.3.2.2 使用java程式碼生成表
建立 java 工程
使用idea 建立 java 的maven工程,取名:activiti01。
加入 maven 依賴的座標(jar 包)
首先需要在 java 工程中加入 ProcessEngine 所需要的 jar 包,包括:
activiti-engine-7。0。0。beta1。jar
activiti 依賴的 jar 包:mybatis、 alf4j、 log4j 等
activiti 依賴的 spring 包
mysql資料庫驅動
第三方資料連線池 dbcp
單元測試 Junit-4。12。jar
我們使用 maven 來實現專案的構建,所以應當匯入這些 jar 所對應的座標到 pom。xml 檔案中。
完整的依賴內容如下:
<!—— bpmn 模型處理 ——>
<!—— bpmn 轉換 ——>
<!—— bpmn json資料轉換 ——>
<!—— bpmn 佈局 ——>
<!—— activiti 雲支援 ——>
<!—— mysql驅動 ——>
<!—— mybatis ——>
<!—— 連結池 ——>
<!—— log start ——>
新增log4j日誌配置
我們使用log4j日誌包,可以對日誌進行配置
在resources 下建立log4j。properties
# Set root category priority to INFO and its only appender to CONSOLE。
#log4j。rootCategory=INFO, CONSOLE debug info warn error fatal
log4j。rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE。
log4j。logger。org。apache。axis。enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout。
log4j。appender。CONSOLE=org。apache。log4j。ConsoleAppender
log4j。appender。CONSOLE。layout=org。apache。log4j。PatternLayout
log4j。appender。CONSOLE。layout。ConversionPattern=%d{ISO8601} %-6r[%15。15t] %-5p %30。30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout。
log4j。appender。LOGFILE=org。apache。log4j。FileAppender
log4j。appender。LOGFILE。File=f:\act\activiti。log
log4j。appender。LOGFILE。Append=true
log4j。appender。LOGFILE。layout=org。apache。log4j。PatternLayout
log4j。appender。LOGFILE。layout。ConversionPattern=%d{ISO8601} %-6r[%15。15t] %-5p %30。30c %x - %m\n
新增activiti配置檔案
我們使用activiti提供的預設方式來建立mysql的表。
預設方式的要求是在 resources 下建立
activiti。cfg。xml
檔案,注意:預設方式目錄和檔名不能修改,因為activiti的原始碼中已經設定,到固定的目錄讀取固定檔名的檔案。
<?xml version=“1。0” encoding=“UTF-8”?>
xmlns:xsi=“http://www。w3。org/2001/XMLSchema-instance” xmlns:context=“http://www。springframework。org/schema/context” xmlns:tx=“http://www。springframework。org/schema/tx” xsi:schemaLocation=“http://www。springframework。org/schema/beans http://www。springframework。org/schema/beans/spring-beans。xsd http://www。springframework。org/schema/contex http://www。springframework。org/schema/context/spring-context。xsd http://www。springframework。org/schema/tx http://www。springframework。org/schema/tx/spring-tx。xsd”>
在 activiti。cfg。xml 中進行配置
預設方式要在在
activiti。cfg。xml
中bean的名字叫
processEngineConfiguration
,名字不可修改
在這裡有2中配置方式:一種是單獨配置資料來源,一種是不單獨配置資料來源
1、直接配置
processEngineConfiguration
processEngineConfiguration
用來建立
ProcessEngine
,在建立
ProcessEngine
時會執行資料庫的操作。
<?xml version=“1。0” encoding=“UTF-8”?>
xmlns:xsi=“http://www。w3。org/2001/XMLSchema-instance” xmlns:context=“http://www。springframework。org/schema/context” xmlns:tx=“http://www。springframework。org/schema/tx” xsi:schemaLocation=“http://www。springframework。org/schema/beans http://www。springframework。org/schema/beans/spring-beans。xsd http://www。springframework。org/schema/contex http://www。springframework。org/schema/context/spring-context。xsd http://www。springframework。org/schema/tx http://www。springframework。org/schema/tx/spring-tx。xsd”> <!—— 預設id對應的值 為processEngineConfiguration ——> <!—— processEngine Activiti的流程引擎 ——> class=“org。activiti。engine。impl。cfg。StandaloneProcessEngineConfiguration”> <!—— activiti資料庫表處理策略 ——>
2、配置資料來源後,在
processEngineConfiguration
引用
首先配置資料來源
<?xml version=“1。0” encoding=“UTF-8”?>
xmlns:xsi=“http://www。w3。org/2001/XMLSchema-instance” xmlns:context=“http://www。springframework。org/schema/context” xmlns:tx=“http://www。springframework。org/schema/tx” xsi:schemaLocation=“http://www。springframework。org/schema/beans http://www。springframework。org/schema/beans/spring-beans。xsd http://www。springframework。org/schema/contex http://www。springframework。org/schema/context/spring-context。xsd http://www。springframework。org/schema/tx http://www。springframework。org/schema/tx/spring-tx。xsd”> <!—— 這裡可以使用 連結池 dbcp——> class=“org。activiti。engine。impl。cfg。StandaloneProcessEngineConfiguration”> <!—— 引用資料來源 上面已經設定好了——> <!—— activiti資料庫表處理策略 ——>
java類編寫程式生成表
建立一個測試類,呼叫activiti的工具類,生成acitivti需要的資料庫表。
直接使用activiti提供的工具類
ProcessEngines
,會預設讀取classpath下的
activiti。cfg。xml
檔案,讀取其中的資料庫配置,建立
ProcessEngine
,在建立
ProcessEngine
時會自動建立表。
程式碼如下:
package com。itheima。activiti01。test;
import org。activiti。engine。ProcessEngine;
import org。activiti。engine。ProcessEngineConfiguration;
import org。junit。Test;
public class TestDemo {
/**
* 生成 activiti的資料庫表
*/
@Test
public void testCreateDbTable() {
//使用classpath下的activiti。cfg。xml中的配置建立processEngine
ProcessEngine processEngine = ProcessEngines。getDefaultProcessEngine();
System。out。println(processEngine);
}
}
說明:
執行以上程式段即可完成 activiti 表建立,透過改變
activiti。cfg。xml
中
databaseSchemaUpdate
引數的值執行不同的資料表處理策略。
上 邊 的 方法
getDefaultProcessEngine
方法在執行時,從
activiti。cfg。xml
中找固定的名稱
processEngineConfiguration
。
在測試程式執行過程中,idea的控制檯會輸出日誌,說明程式正在建立資料表,類似如下,注意紅線內容:
執行完成後我們檢視資料庫, 建立了 25 張表,結果如下:
到這,我們就完成activiti執行需要的資料庫和表的建立。
3.4 表結構介紹
3.4.1 表的命名規則和作用
看到剛才建立的表,我們發現Activiti 的表都以
ACT_
開頭。
第二部分是表示表的用途的兩個字母標識。用途也和服務的 API 對應。
ACT_RE
:‘RE’表示 repository。這個字首的表包含了流程定義和流程靜態資源 (圖片,規則,等等)。
ACT_RU
:’RU’表示 runtime。這些執行時的表,包含流程例項,任務,變數,非同步任務,等執行中的資料。Activiti 只在流程例項執行過程中儲存這些資料, 在流程結束時就會刪除這些記錄。這樣執行時表可以一直很小速度很快。
ACT_HI
:‘HI’表示 history。這些表包含歷史資料,比如歷史流程例項, 變數,任務等等。
ACT_GE
:GE 表示 general。通用資料, 用於不同場景下
3.4.2 Activiti資料表介紹
四、Activiti類關係圖
上面我們完成了Activiti資料庫表的生成,java程式碼中我們呼叫Activiti的工具類,下面來了解Activiti的類關係
4.1 類關係圖
在新版本中,我們透過實驗可以發現
IdentityService
,
FormService
兩個Serivce都已經刪除了。
所以後面我們對於這兩個Service也不講解了,但老版本中還是有這兩個Service,同學們需要了解一下
4.2 activiti.cfg.xml
activiti的引擎配置檔案,包括:
ProcessEngineConfiguration
的定義、資料來源定義、事務管理器等,此檔案其實就是一個spring配置檔案。
4.3 流程引擎配置類
流程引擎的配置類(
ProcessEngineConfiguration
),透過
ProcessEngineConfiguration
可以建立工作流引擎
ProceccEngine
,常用的兩種方法如下:
4.3.1 StandaloneProcessEngineConfiguration
使用
StandaloneProcessEngineConfigurationActiviti
可以單獨執行,來建立
ProcessEngine
,
Activiti
會自己處理事務。
配置檔案方式:
通常在
activiti。cfg。xml
配置檔案中定義一個id為
processEngineConfiguration
的bean。
方法如下:
class=“org。activiti。engine。impl。cfg。StandaloneProcessEngineConfiguration”> <!——配置資料庫相關的資訊——> <!——資料庫驅動——> <!——資料庫連結——> <!——資料庫使用者名稱——> <!——資料庫密碼——> <!——actviti資料庫表在生成時的策略 true - 如果資料庫中已經存在相應的表,那麼直接使用,如果不存在,那麼會建立——>
還可以加入連線池:
<?xml version=“1。0” encoding=“UTF-8”?>
xmlns:xsi=“http://www。w3。org/2001/XMLSchema-instance” xmlns:context=“http://www。springframework。org/schema/context” xmlns:tx=“http://www。springframework。org/schema/tx” xsi:schemaLocation=“http://www。springframework。org/schema/beans http://www。springframework。org/schema/beans/spring-beans。xsd http://www。springframework。org/schema/contex http://www。springframework。org/schema/context/spring-context。xsd http://www。springframework。org/schema/tx http://www。springframework。org/schema/tx/spring-tx。xsd”> <!——在預設方式下 bean的id 固定為 processEngineConfiguration——> class=“org。activiti。engine。impl。cfg。StandaloneProcessEngineConfiguration”> <!——引入上面配置好的 連結池——> <!——actviti資料庫表在生成時的策略 true - 如果資料庫中已經存在相應的表,那麼直接使用,如果不存在,那麼會建立——>
4.3.2 SpringProcessEngineConfiguration
透過
org。activiti。spring。SpringProcessEngineConfiguration
與Spring整合。
建立spring與activiti的整合配置檔案:
activity-spring。cfg。xml
(名稱可修改)
xmlns:xsi=“http://www。w3。org/2001/XMLSchema-instance” xmlns:mvc=“http://www。springframework。org/schema/mvc” xmlns:context=“http://www。springframework。org/schema/context” xmlns:aop=“http://www。springframework。org/schema/aop” xmlns:tx=“http://www。springframework。org/schema/tx” xsi:schemaLocation=“http://www。springframework。org/schema/beans http://www。springframework。org/schema/beans/spring-beans-3。1。xsd http://www。springframework。org/schema/mvc http://www。springframework。org/schema/mvc/spring-mvc-3。1。xsd http://www。springframework。org/schema/context http://www。springframework。org/schema/context/spring-context-3。1。xsd http://www。springframework。org/schema/aop http://www。springframework。org/schema/aop/spring-aop-3。1。xsd http://www。springframework。org/schema/tx http://www。springframework。org/schema/tx/spring-tx-3。1。xsd ”> <!—— 工作流引擎配置bean ——> <!—— 資料來源 ——> <!—— 使用spring事務管理器 ——> <!—— 資料庫策略 ——> <!—— activiti的定時任務關閉 ——> <!—— 流程引擎 ——> <!—— 資源服務service ——> factory-method=“getRepositoryService” /> <!—— 流程執行service ——> factory-method=“getRuntimeService” /> <!—— 任務管理service ——> factory-method=“getTaskService” /> <!—— 歷史管理service ——> <!—— 使用者管理service ——> <!—— 引擎管理service ——> <!—— 資料來源 ——> <!—— 事務管理器 ——> class=“org。springframework。jdbc。datasource。DataSourceTransactionManager”> <!—— 通知 ——> <!—— 傳播行為 ——> <!—— 切面,根據具體專案修改切點配置 ——>
建立
processEngineConfiguration
ProcessEngineConfiguration configuration = ProcessEngineConfiguration。createProcessEngineConfigurationFromResource(“activiti。cfg。xml”)
上邊的程式碼要求
activiti。cfg。xml
中必須有一個
processEngineConfiguration
的bean
也可以使用下邊的方法,更改bean 的名字:
ProcessEngineConfiguration。createProcessEngineConfigurationFromResource(String resource, String beanName);
4.4 工作流引擎建立
工作流引擎(ProcessEngine),相當於一個門面介面,透過
ProcessEngineConfiguration
建立
processEngine
,透過
ProcessEngine
建立各個service介面。
4.4.1 預設建立方式
將
activiti。cfg。xml
檔名及路徑固定,且
activiti。cfg。xml
檔案中有
processEngineConfiguration
的配置, 可以使用如下程式碼建立
processEngine
:
//直接使用工具類 ProcessEngines,使用classpath下的activiti。cfg。xml中的配置建立processEngine
ProcessEngine processEngine = ProcessEngines。getDefaultProcessEngine();
System。out。println(processEngine);
4.4.2 一般建立方式
//先構建ProcessEngineConfiguration
ProcessEngineConfiguration configuration = ProcessEngineConfiguration。createProcessEngineConfigurationFromResource(“activiti。cfg。xml”);
//透過ProcessEngineConfiguration建立ProcessEngine,此時會建立資料庫
ProcessEngine processEngine = configuration。buildProcessEngine();
4.5 Servcie服務介面
Service是工作流引擎提供用於進行工作流部署、執行、管理的服務介面,我們使用這些介面可以就是操作服務對應的資料表
4。5。1 Service建立方式
透過ProcessEngine建立Service
方式如下:
RuntimeService runtimeService = processEngine。getRuntimeService();
RepositoryService repositoryService = processEngine。getRepositoryService();
TaskService taskService = processEngine。getTaskService();
4。5。2 Service總覽
簡單介紹:
RepositoryService
是activiti的資源管理類,提供了管理和控制流程釋出包和流程定義的操作。使用工作流建模工具設計的業務流程圖需要使用此service將流程定義檔案的內容部署到計算機。
除了部署流程定義以外還可以:查詢引擎中的釋出包和流程定義。
暫停或啟用釋出包,對應全部和特定流程定義。暫停意味著它們不能再執行任何操作了,啟用是對應的反向操作。獲得多種資源,像是包含在釋出包裡的檔案, 或引擎自動生成的流程圖。
獲得流程定義的pojo版本, 可以用來透過java解析流程,而不必透過xml。
RuntimeService
Activiti的流程執行管理類。可以從這個服務類中獲取很多關於流程執行相關的資訊
TaskService
Activiti的任務管理類。可以從這個類中獲取任務的資訊。
HistoryService
Activiti的歷史管理類,可以查詢歷史資訊,執行流程時,引擎會儲存很多資料(根據配置),比如流程例項啟動時間,任務的參與者, 完成任務的時間,每個流程例項的執行路徑,等等。這個服務主要透過查詢功能來獲得這些資料。
ManagementService
Activiti的引擎管理類,提供了對 Activiti 流程引擎的管理和維護功能,這些功能不在工作流驅動的應用程式中使用,主要用於 Activiti 系統的日常維護。
五、Activiti入門
在本章內容中,我們來建立一個Activiti工作流,並啟動這個流程。
建立Activiti工作流主要包含以下幾步:
定義流程,按照BPMN的規範,使用流程定義工具,用流程符號把整個流程描述出來
部署流程,把畫好的流程定義檔案,載入到資料庫中,生成表的資料
啟動流程,使用java程式碼來操作資料庫表中的內容
5.1 流程符號
BPMN 2。0是業務流程建模符號2。0的縮寫。
它由Business Process Management Initiative這個非營利協會建立並不斷髮展。作為一種標識,BPMN 2。0是使用一些符號來明確業務流程設計流程圖的一整套符號規範,它能增進業務建模時的溝通效率。
目前BPMN2。0是最新的版本,它用於在BPM上下文中進行佈局和視覺化的溝通。
接下來我們先來了解在流程設計中常見的 符號。
BPMN2。0的基本符合主要包含:
事件 Event
活動 Activity
活動是工作或任務的一個通用術語。一個活動可以是一個任務,還可以是一個當前流程的子處理流程;其次,你還可以為活動指定不同的型別。常見活動如下:
閘道器 GateWay
閘道器用來處理決策,有幾種常用閘道器需要了解:
排他閘道器 (x)
——只有一條路徑會被選擇。流程執行到該閘道器時,按照輸出流的順序逐個計算,當條件的計算結果為true時,繼續執行當前閘道器的輸出流;
如果多條線路計算結果都是 true,則會執行第一個值為 true 的線路。如果所有閘道器計算結果沒有true,則引擎會丟擲異常。
排他閘道器需要和條件順序流結合使用,default 屬性指定預設順序流,當所有的條件不滿足時會執行預設順序流。
並行閘道器 (+)
——所有路徑會被同時選擇
拆分 —— 並行執行所有輸出順序流,為每一條順序流建立一個並行執行線路。
合併 —— 所有從並行閘道器拆分並執行完成的線路均在此等候,直到所有的線路都執行完成才繼續向下執行。
包容閘道器 (+)
—— 可以同時執行多條線路,也可以在閘道器上設定條件
拆分 —— 計算每條線路上的表示式,當表示式計算結果為true時,建立一個並行線路並繼續執行
合併 —— 所有從並行閘道器拆分並執行完成的線路均在此等候,直到所有的線路都執行完成才繼續向下執行。
事件閘道器 (+)
—— 專門為中間捕獲事件設定的,允許設定多個輸出流指向多個不同的中間捕獲事件。當流程執行到事件閘道器後,流程處於等待狀態,需要等待丟擲事件才能將等待狀態轉換為活動狀態。
流向 Flow
流是連線兩個流程節點的連線。常見的流向包含以下幾種:
5.2 流程設計器使用
Activiti-Designer使用
Palette(畫板)
在idea中安裝外掛即可使用,畫板中包括以下結點:
Connection—連線
Event—事件
Task—任務
Gateway—閘道器
Container—容器
Boundary event—邊界事件
Intermediate event- -中間事件
流程圖設計完畢儲存生成。bpmn檔案
新建流程(IDEA工具)
首先選中存放圖形的目錄(選擇resources下的bpmn目錄),點選選單:
New -> BpmnFile
,如圖:
彈出如下圖所示框,輸入evection 表示 出差審批流程:
起完名字evection後(預設副檔名為bpmn),就可以看到流程設計頁面,如圖所示:
左側區域是繪圖區,右側區域是palette畫板區域
滑鼠先點選畫板的元素即可在左側繪圖
繪製流程
使用滑板來繪製流程,透過從右側把圖示拖拽到左側的畫板,最終效果如下:
指定流程定義Key
流程定義key即流程定義的標識,透過properties檢視檢視流程的key
指定任務負責人
在properties檢視指定每個任務結點的負責人,如:填寫出差申請的負責人為 zhangsan
經理審批負責人為 jerry
總經理審批負責人為 jack
財務審批負責人為 rose
六、流程操作
6.1 流程定義
概述
流程定義是線下按照bpmn2。0標準去描述 業務流程,通常使用idea中的外掛對業務流程進行建模。IDEA外掛介紹:IDEA 值得推薦的十幾款優秀外掛,狂,拽,屌!
使用idea下的designer設計器繪製流程,並會生成兩個檔案:。bpmn和。png
.bpmn檔案
使用activiti-desinger設計業務流程,會生成。bpmn檔案,上面我們已經建立好了bpmn檔案
BPMN 2。0根節點是definitions節點。這個元素中,可以定義多個流程定義(不過我們建議每個檔案只包含一個流程定義, 可以簡化開發過程中的維護難度)。
注意,definitions元素 最少也要包含xmlns 和 targetNamespace的宣告。targetNamespace可以是任意值,它用來對流程例項進行分類。
流程定義部分:定義了流程每個結點的描述及結點之間的流程流轉。
流程佈局定義:定義流程每個結點在流程圖上的位置座標等資訊。
生成.png圖片檔案
IDEA工具中的操作方式
1、修改檔案字尾為xml
首先將evection。bpmn檔案改名為evection。xml,如下圖:
evection。xml修改前的bpmn檔案,效果如下:
2、使用designer設計器開啟.xml檔案
在evection。xml檔案上面,點右鍵並選擇Diagrams選單,再選擇
Show BPMN2。0 Designer…
3、檢視開啟的檔案
開啟後,卻出現亂碼,如圖:
4、解決中文亂碼
1、開啟Settings,找到File Encodings,把encoding的選項都選擇UTF-8
2、開啟IDEA安裝路徑,找到如下的安裝目錄
根據自己所安裝的版本來決定,我使用的是64位的idea,所以在
idea64。exe。vmoptions
檔案的最後一行追加一條命令:
-Dfile。encoding=UTF-8
如下所示:
一定注意,不要有空格,否則重啟IDEA時會打不開,然後 重啟IDEA。
如果以上方法已經做完,還出現亂碼,就再修改一個檔案,並在檔案的末尾新增:
-Dfile。encoding=UTF-8
,然後重啟idea,如圖:
最後重新在evection。xml檔案上面,點右鍵並選擇Diagrams選單,再選擇
Show BPMN2。0 Designer…
,看到生成圖片,如圖:
到此,解決亂碼問題
5、匯出為圖片檔案
點選
Export To File
的小圖示,開啟如下視窗,注意填寫檔名及副檔名,選擇好儲存圖片的位置:
然後,我們把png檔案複製到resources下的bpmn目錄,並且把evection。xml改名為evection。bpmn。
6.2 流程定義部署
概述
將上面在設計器中定義的流程部署到activiti資料庫中,就是流程定義部署。
透過呼叫activiti的api將流程定義的bpmn和png兩個檔案一個一個新增部署到activiti中,也可以將兩個檔案打成zip包進行部署。
單個檔案部署方式
分別將bpmn檔案和png圖片檔案部署。
public class ActivitiDemo {
/**
* 部署流程定義
*/
@Test
public void testDeployment(){
// 1、建立ProcessEngine
ProcessEngine processEngine = ProcessEngines。getDefaultProcessEngine();
// 2、得到RepositoryService例項
RepositoryService repositoryService = processEngine。getRepositoryService();
// 3、使用RepositoryService進行部署
Deployment deployment = repositoryService。createDeployment()
。addClasspathResource(“bpmn/evection。bpmn”) // 新增bpmn資源
。addClasspathResource(“bpmn/evection。png”) // 新增png資源
。name(“出差申請流程”)
。deploy();
// 4、輸出部署資訊
System。out。println(“流程部署id:” + deployment。getId());
System。out。println(“流程部署名稱:” + deployment。getName());
}
}
執行此操作後activiti會將上邊程式碼中指定的bpm檔案和圖片檔案儲存在activiti資料庫。
壓縮包部署方式
將
evection。bpmn
和
evection。png
壓縮成zip包。
@Test
public void deployProcessByZip() {
// 定義zip輸入流
InputStream inputStream = this
。getClass()
。getClassLoader()
。getResourceAsStream(
“bpmn/evection。zip”);
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
// 獲取repositoryService
RepositoryService repositoryService = processEngine
。getRepositoryService();
// 流程部署
Deployment deployment = repositoryService。createDeployment()
。addZipInputStream(zipInputStream)
。deploy();
System。out。println(“流程部署id:” + deployment。getId());
System。out。println(“流程部署名稱:” + deployment。getName());
}
執行此操作後activiti會將上邊程式碼中指定的bpm檔案和圖片檔案儲存在activiti資料庫。
操作資料表
流程定義部署後操作activiti的3張表如下:
act_re_deployment
流程定義部署表,每部署一次增加一條記錄
act_re_procdef
流程定義表,部署每個新的流程定義都會在這張表中增加一條記錄
act_ge_bytearray
流程資源表
接下來我們來看看,寫入了什麼資料:
SELECT * FROM act_re_deployment #流程定義部署表,記錄流程部署資訊
結果:
SELECT * FROM act_re_procdef #流程定義表,記錄流程定義資訊
結果:
注意,KEY 這個欄位是用來唯一識別不同流程的關鍵字
SELECT * FROM act_ge_bytearray #資源表
結果:
注意:
act_re_deployment
和
act_re_procdef
一對多關係,一次部署在流程部署表生成一條記錄,但一次部署可以部署多個流程定義,每個流程定義在流程定義表生成一條記錄。每一個流程定義在
act_ge_bytearray
會存在兩個資源記錄,bpmn和png。
建議:一次部署一個流程,這樣部署表和流程定義表是一對一有關係,方便讀取流程部署及流程定義資訊。
6.3 啟動流程例項
流程定義部署在activiti後就可以透過工作流管理業務流程了,也就是說上邊部署的出差申請流程可以使用了。
針對該流程,啟動一個流程表示發起一個新的出差申請單,這就相當於java類與java物件的關係,類定義好後需要new建立一個物件使用,當然可以new多個物件。對於請出差申請流程,張三發起一個出差申請單需要啟動一個流程例項,出差申請單發起一個出差單也需要啟動一個流程例項。
程式碼如下:
/**
* 啟動流程例項
*/
@Test
public void testStartProcess(){
// 1、建立ProcessEngine
ProcessEngine processEngine = ProcessEngines。getDefaultProcessEngine();
// 2、獲取RunTimeService
RuntimeService runtimeService = processEngine。getRuntimeService();
// 3、根據流程定義Id啟動流程
ProcessInstance processInstance = runtimeService
。startProcessInstanceByKey(“myEvection”);
// 輸出內容
System。out。println(“流程定義id:” + processInstance。getProcessDefinitionId());
System。out。println(“流程例項id:” + processInstance。getId());
System。out。println(“當前活動Id:” + processInstance。getActivityId());
}
輸出內容如下:
操作資料表
act_hi_actinst
流程例項執行歷史
act_hi_identitylink
流程的參與使用者歷史資訊
act_hi_procinst
流程例項歷史資訊
act_hi_taskinst
流程任務歷史資訊
act_ru_execution
流程執行資訊
act_ru_identitylink
流程的參與使用者資訊
act_ru_task
任務資訊
6.4 任務查詢
流程啟動後,任務的負責人就可以查詢自己當前需要處理的任務,查詢出來的任務都是該使用者的待辦任務。
/**
* 查詢當前個人待執行的任務
*/
@Test
public void testFindPersonalTaskList() {
// 任務負責人
String assignee = “zhangsan”;
ProcessEngine processEngine = ProcessEngines。getDefaultProcessEngine();
// 建立TaskService
TaskService taskService = processEngine。getTaskService();
// 根據流程key 和 任務負責人 查詢任務
List
。processDefinitionKey(“myEvection”) //流程Key
。taskAssignee(assignee)//只查詢該任務負責人的任務
。list();
for (Task task : list) {
System。out。println(“流程例項id:” + task。getProcessInstanceId());
System。out。println(“任務id:” + task。getId());
System。out。println(“任務負責人:” + task。getAssignee());
System。out。println(“任務名稱:” + task。getName());
}
}
輸出結果如下:
流程例項id:2501
任務id:2505
任務負責人:zhangsan
任務名稱:創建出差申請
6.5 流程任務處理
任務負責人查詢待辦任務,選擇任務進行處理,完成任務。
// 完成任務
@Test
public void completTask(){
// 獲取引擎
ProcessEngine processEngine = ProcessEngines。getDefaultProcessEngine();
// 獲取taskService
TaskService taskService = processEngine。getTaskService();
// 根據流程key 和 任務的負責人 查詢任務
// 返回一個任務物件
Task task = taskService。createTaskQuery()
。processDefinitionKey(“myEvection”) //流程Key
。taskAssignee(“zhangsan”) //要查詢的負責人
。singleResult();
// 完成任務,引數:任務id
taskService。complete(task。getId());
}
6.6 流程定義資訊查詢
查詢流程相關資訊,包含流程定義,流程部署,流程定義版本
/**
* 查詢流程定義
*/
@Test
public void queryProcessDefinition(){
// 獲取引擎
ProcessEngine processEngine = ProcessEngines。getDefaultProcessEngine();
// repositoryService
RepositoryService repositoryService = processEngine。getRepositoryService();
// 得到ProcessDefinitionQuery 物件
ProcessDefinitionQuery processDefinitionQuery = repositoryService。createProcessDefinitionQuery();
// 查詢出當前所有的流程定義
// 條件:processDefinitionKey =evection
// orderByProcessDefinitionVersion 按照版本排序
// desc倒敘
// list 返回集合
List
。orderByProcessDefinitionVersion()
。desc()
。list();
// 輸出流程定義資訊
for (ProcessDefinition processDefinition : definitionList) {
System。out。println(“流程定義 id=”+processDefinition。getId());
System。out。println(“流程定義 name=”+processDefinition。getName());
System。out。println(“流程定義 key=”+processDefinition。getKey());
System。out。println(“流程定義 Version=”+processDefinition。getVersion());
System。out。println(“流程部署ID =”+processDefinition。getDeploymentId());
}
}
輸出結果:
流程定義id:myEvection:1:4
流程定義名稱:出差申請單
流程定義key:myEvection
流程定義版本:1
6.7 流程刪除
public void deleteDeployment() {
// 流程部署id
String deploymentId = “1”;
ProcessEngine processEngine = ProcessEngines。getDefaultProcessEngine();
// 透過流程引擎獲取repositoryService
RepositoryService repositoryService = processEngine
。getRepositoryService();
//刪除流程定義,如果該流程定義已有流程例項啟動則刪除時出錯
repositoryService。deleteDeployment(deploymentId);
//設定true 級聯刪除流程定義,即使該流程有流程例項啟動也可以刪除,設定為false非級別刪除方式,如果流程
//repositoryService。deleteDeployment(deploymentId, true);
}
說明:
使用repositoryService刪除流程定義,歷史表資訊不會被刪除
如果該流程定義下沒有正在執行的流程,則可以用普通刪除。
如果該流程定義下存在已經執行的流程,使用普通刪除報錯,可用級聯刪除方法將流程及相關記錄全部刪除。
先刪除沒有完成流程節點,最後就可以完全刪除流程定義資訊
專案開發中級聯刪除操作一般只開放給超級管理員使用。
6.8 流程資源下載
現在我們的流程資原始檔已經上傳到資料庫了,如果其他使用者想要檢視這些資原始檔,可以從資料庫中把資原始檔下載到本地。
解決方案有:
jdbc對blob型別,clob型別資料讀取出來,儲存到檔案目錄
使用activiti的api來實現
使用commons-io。jar 解決IO的操作
引入commons-io依賴包
透過流程定義物件獲取流程定義資源,獲取bpmn和png
import org。apache。commons。io。IOUtils;
@Test
public void deleteDeployment(){
// 獲取引擎
ProcessEngine processEngine = ProcessEngines。getDefaultProcessEngine();
// 獲取repositoryService
RepositoryService repositoryService = processEngine。getRepositoryService();
// 根據部署id 刪除部署資訊,如果想要級聯刪除,可以新增第二個引數,true
repositoryService。deleteDeployment(“1”);
}
public void queryBpmnFile() throws IOException {
// 1、得到引擎
ProcessEngine processEngine = ProcessEngines。getDefaultProcessEngine();
// 2、獲取repositoryService
RepositoryService repositoryService = processEngine。getRepositoryService();
// 3、得到查詢器:ProcessDefinitionQuery,設定查詢條件,得到想要的流程定義
ProcessDefinition processDefinition = repositoryService。createProcessDefinitionQuery()
。processDefinitionKey(“myEvection”)
。singleResult();
// 4、透過流程定義資訊,得到部署ID
String deploymentId = processDefinition。getDeploymentId();
// 5、透過repositoryService的方法,實現讀取圖片資訊和bpmn資訊
// png圖片的流
InputStream pngInput = repositoryService。getResourceAsStream(deploymentId, processDefinition。getDiagramResourceName());
// bpmn檔案的流
InputStream bpmnInput = repositoryService。getResourceAsStream(deploymentId, processDefinition。getResourceName());
// 6、構造OutputStream流
File file_png = new File(“d:/evectionflow01。png”);
File file_bpmn = new File(“d:/evectionflow01。bpmn”);
FileOutputStream bpmnOut = new FileOutputStream(file_bpmn);
FileOutputStream pngOut = new FileOutputStream(file_png);
// 7、輸入流,輸出流的轉換
IOUtils。copy(pngInput,pngOut);
IOUtils。copy(bpmnInput,bpmnOut);
// 8、關閉流
pngOut。close();
bpmnOut。close();
pngInput。close();
bpmnInput。close();
}
說明:
deploymentId
為流程部署ID
resource_name
為
act_ge_bytearray
表中NAME_列的值
使用
repositoryService
的
getDeploymentResourceNames
方法可以獲取指定部署下得所有檔案的名稱
使用
repositoryService
的
getResourceAsStream
方法傳入部署ID和資源圖片名稱可以獲取部署下指定名稱檔案的輸入流
最後的將輸入流中的圖片資源進行輸出。
6.9 流程歷史資訊的檢視
即使流程定義已經刪除了,流程執行的歷史資訊透過前面的分析,依然儲存在activiti的
act_hi_*
相關的表中。所以我們還是可以查詢流程執行的歷史資訊,可以透過
HistoryService
來檢視相關的歷史記錄。
/**
* 檢視歷史資訊
*/
@Test
public void findHistoryInfo(){
// 獲取引擎
ProcessEngine processEngine = ProcessEngines。getDefaultProcessEngine();
// 獲取HistoryService
HistoryService historyService = processEngine。getHistoryService();
// 獲取 actinst表的查詢物件
HistoricActivityInstanceQuery instanceQuery = historyService。createHistoricActivityInstanceQuery();
// 查詢 actinst表,條件:根據 InstanceId 查詢
// instanceQuery。processInstanceId(“2501”);
// 查詢 actinst表,條件:根據 DefinitionId 查詢
instanceQuery。processDefinitionId(“myEvection:1:4”);
// 增加排序操作,orderByHistoricActivityInstanceStartTime 根據開始時間排序 asc 升序
instanceQuery。orderByHistoricActivityInstanceStartTime()。asc();
// 查詢所有內容
List
// 輸出
for (HistoricActivityInstance hi : activityInstanceList) {
System。out。println(hi。getActivityId());
System。out。println(hi。getActivityName());
System。out。println(hi。getProcessDefinitionId());
System。out。println(hi。getProcessInstanceId());
System。out。println(“<==========================>”);
}
}
總結
基本功能介紹以及完成了,如果還需要更加高階的功能比如掛起、啟用流程例項、流程變數等請參考
https://
andyoung。blog。csdn。net/
article/details/118345330
工作流引擎 Activiti 與 Spring boot 結合會是開發跟簡單,不如來看下
https://
andyoung。blog。csdn。net/
article/details/118372175
https://
blog。csdn。net/agonie201
218/
article/details/118198535
下一篇:離心泵型號及引數大全