文章目錄
- 1 工作流介紹
- 1_工作流概念介紹
- 2 工作流系統
- 3 適用行業
- 4 具體應用
- 5 實現方式
- 2 Activiti介紹
- 1_BPM
- 2 BPM 軟件
- 3 BPMN
- 3 使用步驟
- 1_部署 activiti
- 2 流程定義
- 3 流程定義部署
- 4 啟動一個流程實例
- 5 用戶查詢待辦任務(Task)
- 6 用戶辦理任務
- 7 流程結束
- 4 Activiti應用
- 1_Activiti的基本使用
- 1 創建Maven項目
- 2 log4j
- 3 添加Activiti配置文件
- 4 Java程序生成表結構
- 2 表結構介紹
- 1 表的命名規則和作用
- 2 Activiti數據表介紹
- 3 ProcessEngine創建方式
- 4 Servcie服務接口
- 1 Service創建方式
- 2 Service總覽
- 5 流程繪制
- 1 繪制插件
- 2 繪制流程
- 3 圖標介紹
- 5 Activiti流程操作
- 1_流程的部署
- 1 單個文件部署
- 2 部署zip文件
- 3 操作數據表
- 2 啟動流程實例
- 3 任務查找
- 4 流程任務處理
- 5 流程定義的查詢
- 6 流程的刪除
- 7 流程資源的下載
- 8 流程歷史信息查看
1 工作流介紹
1_工作流概念介紹
工作流(Workflow),就是通過計算機對業務流程自動化執行管理。
它主要解決的是“使在多個參與者之間按照某種預定義的規則自動進行傳遞文檔、信息或任務的過程,從而實現某個預期的業務目標,或者促使此目標的實現”。
2 工作流系統
一個軟件系統中具有工作流的功能,我們把它稱為工作流系統,一個系統中工作流的功能是什么?
就是對系統的業務流程進行自動化管理,所以工作流是建立在業務流程的基礎上,所以一個軟件的系統核心根本上還是系統的業務流程,工作流只是協助進行業務流程管理。
即使沒有工作流業務系統也可以開發運行,只不過有了工作流可以更好的管理業務流程,提高系統的可擴展性。
3 適用行業
消費品行業,制造業,電信服務業,銀證險等金融服務業,物流服務業,物業服務業,物業管理,大中型進出口貿易公司,政府事業機構,研究院所及教育服務業等,特別是大的跨國企業和集團公司。
4 具體應用
1、關鍵業務流程:訂單、報價處理、合同審核、客戶電話處理、供應鏈管理等
2、行政管理類:出差申請、加班申請、請假申請、用車申請、各種辦公用品申請、購買申請、日報周報等凡是原來手工流轉處理的行政表單。
3、人事管理類:員工培訓安排、績效考評、職位變動處理、員工檔案信息管理等。
4、財務相關類:付款請求、應收款處理、日常報銷處理、出差報銷、預算和計劃申請等。
5、客戶服務類:客戶信息管理、客戶投訴、請求處理、售后服務管理等。
6、特殊服務類:ISO系列對應流程、質量管理對應流程、產品數據信息管理、貿易公司報關處理、物流公司貨物跟蹤處理等各種通過表單逐步手工流轉完成的任務均可應用工作流軟件自動規范地實施。
5 實現方式
在沒有專門的工作流引擎之前,我們之前為了實現流程控制,通常的做法就是采用狀態字段的值來跟蹤流程的變化情況。
這樣不用角色的用戶,通過狀態字段的取值來決定記錄是否顯示。
針對有權限可以查看的記錄,當前用戶根據自己的角色來決定審批是否合格的操作。
如果合格將狀態字段設置一個值,來代表合格;當然如果不合格也需要設置一個值來代表不合格的情況。
這是一種最為原始的方式。通過狀態字段雖然做到了流程控制,但是當我們的流程發生變更的時候,這種方式所編寫的代碼也要進行調整。
那么有沒有專業的方式來實現工作流的管理呢?并且可以做到業務流程變化之后,我們的程序可以不用改變,如果可以實現這樣的效果,那么我們的業務系統的適應能力就得到了極大提升。
2 Activiti介紹
Alfresco 軟件在 2010 年 5 月 17 日宣布 Activiti 業務流程管理(BPM)開源項目的正式啟動,其首席架構師由業務流程管理BPM的專家 Tom Baeyens 擔任,Tom Baeyens 就是原來 jbpm 的架構師,而 jbpm 是一個非常有名的工作流引擎,當然 activiti 也是一個工作流引擎。
Activiti 是一個工作流引擎, activiti 可以將業務系統中復雜的業務流程抽取出來,使用專門的建模語言 BPMN2.0 進行定義,業務流程按照預先定義的流程進行執行,實現了系統的流程由 activiti 進行管理,減少業務系統由于流程變更進行系統升級改造的工作量,從而提高系統的健壯性,同時也減少了系統開發維護成本。
官方網站:https://www.activiti.org/
1_BPM
BPM(Business Process Management),即業務流程管理,是一種規范化的構造端到端的業務流程,以持續的提高組織業務效率。
常見商業管理教育如 EMBA、MBA 等均將 BPM 包含在內。
2 BPM 軟件
BPM 軟件就是根據企業中業務環境的變化,推進人與人之間、人與系統之間以及系統與系統之間的整合及調整的經營方法與解決方案的IT工具。
通過 BPM 軟件對企業內部及外部的業務流程的整個生命周期進行建模、自動化、管理監控和優化,使企業成本降低,利潤得以大幅提升。
BPM 軟件在企業中應用領域廣泛,凡是有業務流程的地方都可以 BPM 軟件進行管理,比如企業人事辦公管理、采購流程管理、公文審批流程管理、財務管理等。
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"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test"><process id="myProcess" name="My process" isExecutable="true"><startEvent id="startevent1" name="Start"></startEvent><userTask id="usertask1" name="創建請假單"></userTask><sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow><userTask id="usertask2" name="部門經理審核"></userTask><sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow><userTask id="usertask3" name="人事復核"></userTask><sequenceFlow id="flow3" sourceRef="usertask2" targetRef="usertask3"></sequenceFlow><endEvent id="endevent1" name="End"></endEvent><sequenceFlow id="flow4" sourceRef="usertask3" targetRef="endevent1"></sequenceFlow></process><bpmndi:BPMNDiagram id="BPMNDiagram_myProcess"><bpmndi:BPMNPlane bpmnElement="myProcess" id="BPMNPlane_myProcess"><bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1"><omgdc:Bounds height="35.0" width="35.0" x="130.0" y="160.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1"><omgdc:Bounds height="55.0" width="105.0" x="210.0" y="150.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2"><omgdc:Bounds height="55.0" width="105.0" x="360.0" y="150.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3"><omgdc:Bounds height="55.0" width="105.0" x="510.0" y="150.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1"><omgdc:Bounds height="35.0" width="35.0" x="660.0" y="160.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1"><omgdi:waypoint x="165.0" y="177.0"></omgdi:waypoint><omgdi:waypoint x="210.0" y="177.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2"><omgdi:waypoint x="315.0" y="177.0"></omgdi:waypoint><omgdi:waypoint x="360.0" y="177.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3"><omgdi:waypoint x="465.0" y="177.0"></omgdi:waypoint><omgdi:waypoint x="510.0" y="177.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4"><omgdi:waypoint x="615.0" y="177.0"></omgdi:waypoint><omgdi:waypoint x="660.0" y="177.0"></omgdi:waypoint></bpmndi:BPMNEdge></bpmndi:BPMNPlane></bpmndi:BPMNDiagram>
</definitions>
3 使用步驟
1_部署 activiti
Activiti 是一個工作流引擎(其實就是一堆 jar 包API),業務系統訪問/操作 activiti 的接口,就可以方便的操作流程相關數據,這樣就可以把工作流環境與業務系統的環境集成在一起。
2 流程定義
使用activiti
流程建模工具(activity-designer)定義業務流程(.bpmn文件)。
.bpmn文件就是業務流程定義文件,通過xml定義業務流程。
3 流程定義部署
activiti 部署業務流程定義(.bpmn文件)。
使用 activiti 提供的 api 把流程定義內容存儲起來,在 Activiti 執行過程中可以查詢定義的內容。
Activiti執行把流程定義內容存儲在數據庫中。
4 啟動一個流程實例
流程實例也叫:ProcessInstance。
啟動一個流程實例表示開始一次業務流程的運行。
在員工請假流程定義部署完成后,如果張三要請假就可以啟動一個流程實例,如果李四要請假也啟動一個流程實例,兩個流程的執行互相不影響。
5 用戶查詢待辦任務(Task)
因為現在系統的業務流程已經交給 activiti 管理,通過 activiti 就可以查詢當前流程執行到哪了,當前用戶需要辦理什么任務了,這些 activiti 幫我們管理了,而不需要開發人員自己編寫在sql
語句查詢。
6 用戶辦理任務
用戶查詢待辦任務后,就可以辦理某個任務,如果這個任務辦理完成還需要其它用戶辦理,比如采購單創建后由部門經理審核,這個過程也是由activiti
幫我們完成了。
7 流程結束
當任務辦理完成沒有下一個任務結點了,這個流程實例就完成了。
4 Activiti應用
1_Activiti的基本使用
1 創建Maven項目
創建一個普通的Maven項目,并添加相關的依賴
<properties><slf4j.version>1.6.6</slf4j.version><log4j.version>1.2.12</log4j.version><activiti.version>7.0.0.Beta1</activiti.version>
</properties>
<dependencies><dependency><groupId>org.activiti</groupId><artifactId>activiti-engine</artifactId><version>${activiti.version}</version></dependency><dependency><groupId>org.activiti</groupId><artifactId>activiti-spring</artifactId><version>${activiti.version}</version></dependency><!-- bpmn 模型處理 --><dependency><groupId>org.activiti</groupId><artifactId>activiti-bpmn-model</artifactId><version>${activiti.version}</version></dependency><!-- bpmn 轉換 --><dependency><groupId>org.activiti</groupId><artifactId>activiti-bpmn-converter</artifactId><version>${activiti.version}</version></dependency><!-- bpmn json數據轉換 --><dependency><groupId>org.activiti</groupId><artifactId>activiti-json-converter</artifactId><version>${activiti.version}</version></dependency><!-- bpmn 布局 --><dependency><groupId>org.activiti</groupId><artifactId>activiti-bpmn-layout</artifactId><version>${activiti.version}</version><exclusions><exclusion><groupId>com.github.jgraph</groupId><artifactId>jgraphx</artifactId></exclusion></exclusions></dependency><!-- activiti 云支持 --><dependency><groupId>org.activiti.cloud</groupId><artifactId>activiti-cloud-services-api</artifactId><version>${activiti.version}</version></dependency><!-- mysql驅動 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.26</version></dependency><!-- mybatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.5</version></dependency><!-- 鏈接池 --><dependency><groupId>commons-dbcp</groupId><artifactId>commons-dbcp</artifactId><version>1.4</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency><!-- log start --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>${log4j.version}</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>${slf4j.version}</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>${slf4j.version}</version></dependency></dependencies>
2 log4j
添加一個日志文件 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=d:\log\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
3 添加Activiti配置文件
Activiti 的默認的使用方式是要求我們在 resources下創建activiti.cfg.xml
文件,默認的方式的名稱是不能修改的。
在配置文件中我們有兩種配置方式:一種是單獨配置數據源,另一種是不單獨配置數據源
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration" id="processEngineConfiguration"><property name="jdbcDriver" value="com.mysql.cj.jdbc.Driver"/><property name="jdbcUrl" value="jdbc:mysql://192.168.200.129:3306/activiti?characterEncoding=utf-8&nullCatalogMeansCurrent=true&serverTimezone=UTC" /><property name="jdbcUsername" value="root" /><property name="jdbcPassword" value="123456" /><property name="databaseSchemaUpdate" value="true" /><!--<property name="dataSource" ref="dataSource" />--></bean><bean class="org.apache.commons.dbcp.BasicDataSource" id="dataSource"><property name="driverClassName" value="com.mysql.cj.jdbc.Driver" /><property name="url" value="jdbc:mysql://192.168.200.129:3306/activiti?characterEncoding=utf-8&nullCatalogMeansCurrent=true&serverTimezone=UTC" /><property name="username" value="root"/><property name="password" value="123456"/><property name="maxActive" value="3" /><property name="maxIdle" value="2" /></bean>
</beans>
4 Java程序生成表結構
創建一個工具類,調用 Activiti 的工具類來生成activiti
需要的表結構
public class Test01 {/*** 生成Activiti的相關的表結構*/@Testpublic void test01(){// 使用classpath下的activiti.cfg.xml中的配置來創建 ProcessEngine對象ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();System.out.println(engine);}
}
執行的效果
執行完成后我們查看數據庫,在其中創建了25張表,結果如下:
2 表結構介紹
1 表的命名規則和作用
看到剛才創建的表,我們發現 Activiti 的表都以 ACT_ 開頭。
第二部分是表示表的用途的兩個字母標識。 用途也和服務的 API 對應。
ACT_RE :‘RE’ 表示 repository。 這個前綴的表包含了流程定義和流程靜態資源 (圖片,規則,等等)。
ACT_RU:‘RU’ 表示 runtime。 這些運行時的表,包含流程實例,任務,變量,異步任務,等運行中的數據。 Activiti 只在流程實例執行過程中保存這些數據, 在流程結束時就會刪除這些記錄。 這樣運行時表可以一直很小速度很快。
ACT_HI:‘HI’ 表示 history。 這些表包含歷史數據,比如歷史流程實例, 變量,任務等等。
ACT_GE :GE 表示 general。 通用數據, 用于不同場景下
2 Activiti數據表介紹
表分類 | 表名 | 解釋 |
---|---|---|
一般數據 | ||
[ACT_GE_BYTEARRAY] | 通用的流程定義和流程資源 | |
[ACT_GE_PROPERTY] | 系統相關屬性 | |
流程歷史記錄 | ||
[ACT_HI_ACTINST] | 歷史的流程實例 | |
[ACT_HI_ATTACHMENT] | 歷史的流程附件 | |
[ACT_HI_COMMENT] | 歷史的說明性信息 | |
[ACT_HI_DETAIL] | 歷史的流程運行中的細節信息 | |
[ACT_HI_IDENTITYLINK] | 歷史的流程運行過程中用戶關系 | |
[ACT_HI_PROCINST] | 歷史的流程實例 | |
[ACT_HI_TASKINST] | 歷史的任務實例 | |
[ACT_HI_VARINST] | 歷史的流程運行中的變量信息 | |
流程定義表 | ||
[ACT_RE_DEPLOYMENT] | 部署單元信息 | |
[ACT_RE_MODEL] | 模型信息 | |
[ACT_RE_PROCDEF] | 已部署的流程定義 | |
運行實例表 | ||
[ACT_RU_EVENT_SUBSCR] | 運行時事件 | |
[ACT_RU_EXECUTION] | 運行時流程執行實例 | |
[ACT_RU_IDENTITYLINK] | 運行時用戶關系信息,存儲任務節點與參與者的相關信息 | |
[ACT_RU_JOB] | 運行時作業 | |
[ACT_RU_TASK] | 運行時任務 | |
[ACT_RU_VARIABLE] | 運行時變量表 |
3 ProcessEngine創建方式
前面使用的是 getDefaultProcessEngine() 方法來加載 classpath下的activiti.cfg.xml
文件,有些情況下我們可能沒有按照默認的方式來處理,那這時我們應該怎么辦呢?
/*** 自定義的方式來加載配置文件*/
@Test
public void test02(){// 首先創建ProcessEngineConfiguration對象ProcessEngineConfiguration configuration =ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");// 通過ProcessEngineConfiguration對象來創建 ProcessEngine對象ProcessEngine processEngine = configuration.buildProcessEngine();
}
4 Servcie服務接口
Service是工作流引擎提供用于進行工作流部署、執行、管理的服務接口,我們使用這些接口可以就是操作服務對應的數據表
1 Service創建方式
通過 ProcessEngine 創建 Service 方式如下:
RuntimeService runtimeService = processEngine.getRuntimeService();
RepositoryService repositoryService = processEngine.getRepositoryService();
TaskService taskService = processEngine.getTaskService();
2 Service總覽
service名稱 | service作用 |
---|---|
RepositoryService | activiti的資源管理類 |
RuntimeService | activiti的流程運行管理類 |
TaskService | activiti的任務管理類 |
HistoryService | activiti的歷史管理類 |
ManagerService | activiti的引擎管理類 |
簡單介紹:
RepositoryService
是activiti的資源管理類,提供了管理和控制流程發布包和流程定義的操作。
使用工作流建模工具設計的業務流程圖需要使用此service將流程定義文件的內容部署到計算機。
除了部署流程定義以外還可以:查詢引擎中的發布包和流程定義。
暫停或激活發布包,對應全部和特定流程定義。 暫停意味著它們不能再執行任何操作了,激活是對應的反向操作。獲得多種資源,像是包含在發布包里的文件, 或引擎自動生成的流程圖。
獲得流程定義的pojo版本, 可以用來通過java解析流程,而不必通過xml。
RuntimeService
Activiti 的流程運行管理類,可以從這個服務類中獲取很多關于流程執行相關的信息。
TaskService
Activiti的任務管理類,可以從這個類中獲取任務的信息。
HistoryService
Activiti 的歷史管理類,可以查詢歷史信息,執行流程時,引擎會保存很多數據(根據配置),比如流程實例啟動時間,任務的參與者, 完成任務的時間,每個流程實例的執行路徑,等等。 這個服務主要通過查詢功能來獲得這些數據。
ManagementService
Activiti 的引擎管理類,提供了對 Activiti 流程引擎的管理和維護功能,這些功能不在工作流驅動的應用程序中使用,主要用于 Activiti 系統的日常維護。
5 流程繪制
1 繪制插件
由于 Idea 在2019年之后就沒有再更新維護 Activiti 的設計工具了,那么在高版本的IDEA 中就沒法使用 actiBPM 插件來繪制了(可以使用 Activiti BPMN visualizer),這時可以選擇降低版本來使用,或者使用Eclipse來實現流程的設計。
使用另一款插件
或者Eclipse集成Activiti插件。
創建一個Activiti項目
2 繪制流程
使用Eclipse來繪制流程,通過從右側把圖標拖拽到左側的面板,最終的效果
指定流程的主鍵
指定任務的負責人
在Properties視圖中指定每個任務節點的負責人:
經理審批:lisi
總經理審批:wangwu
財務審批:xiaoming
當我們設置完成后保存文件,會同時生成png圖片
然后將這兩個文件拷貝到IDEA項目中即可
或者使用Idea的 Activiti BPMN visualizer,新建文件
選中文件展開視圖后鼠標右鍵即可添加組件或者連線
3 圖標介紹
流程符號
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
流是連接兩個流程節點的連線。常見的流向包含以下幾種:
流程設計器使用
Palette(畫板)
Connection—連接
Event—事件
Task—任務
Gateway—網關
Container—容器
Boundary event—邊界事件
Intermediate event- -中間事件
5 Activiti流程操作
1_流程的部署
將上面在設計器中定義的流程部署到 activiti 數據庫中,就是我們講的流程部署。
通過調用 Activiti 的 api 將流程定義的 bpmn 和 png 兩個文件一個一個添加部署到 activiti 中,還可以將兩個文件打車zip包部署。
1 單個文件部署
分別將 bpmn 文件和 png 圖片分別部署
/*** 實現文件的單個部署*/
@Test
public void test04(){// 1.獲取ProcessEngine對象ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();// 2.獲取RepositoryService進行部署操作RepositoryService service = engine.getRepositoryService();// 3.使用RepositoryService進行部署操作Deployment deploy = service.createDeployment().addClasspathResource("bpmn/evection.bpmn20.xml") // 添加bpmn資源.addClasspathResource("bpmn/evection.png") // 添加png資源.name("出差申請流程").deploy();// 部署流程// 4.輸出流程部署的信息System.out.println("流程部署的id:" + deploy.getId());System.out.println("流程部署的名稱:" + deploy.getName());
}
日志中查看到相關的輸出信息
2 部署zip文件
將 bpmn 文件和 png 文件兩個打包為一個 zip 文件,統一上傳
/*** 通過一個zip文件來部署操作*/
@Test
public void test05(){// 定義zip文件的輸入流InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("bpmn/evection.zip");// 對 inputStream 做裝飾ZipInputStream zipInputStream = new ZipInputStream(inputStream);ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();RepositoryService repositoryService = engine.getRepositoryService();Deployment deploy = repositoryService.createDeployment().addZipInputStream(zipInputStream).name("出差申請流程").deploy();// 4.輸出流程部署的信息System.out.println("流程部署的id:" + deploy.getId());System.out.println("流程部署的名稱:" + deploy.getName());
}
上傳后的數據庫中的數據和單個文件上傳其實是一樣的。
3 操作數據表
流程定義部署后操作 activiti 中的三張表
act_re_deployment: 流程定義部署表,每部署一次就增加一條記錄
act_re_procdef:流程定義表,部署每個新的流程定義都會在這張表中增加一條記錄
act_ge_bytearray:流程資源表,流程部署的 bpmn文件和png圖片會保存在該表中
2 啟動流程實例
流程定義部署在 Activiti 后就可以通過工作流管理業務流程,也就是說上邊部署的出差申請流程可以使用了。
針對該流程,啟動一個流程表示發起一個新的出差申請單,這就相當于 Java 類和 Java 對象的關系,類定義好了后需要 new 創建一個對象使用,當然可以 new 出多個對象來,對于出差申請流程,張三可以發起一個出差申請單需要啟動一個流程實例。
/*** 啟動一個流程實例*/
@Test
public void test06(){// 1.創建ProcessEngine對象ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();// 2.獲取RuntimeService對象RuntimeService runtimeService = engine.getRuntimeService();// 3.根據流程定義的id啟動流程String id= "evection";ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(id);// 4.輸出相關的流程實例信息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 任務信息
3 任務查找
流程啟動后,任務的負責人就可以查詢自己當前能夠處理的任務了,查詢出來的任務都是當前用戶的待辦任務
/*** 任務查詢*/
@Test
public void test07(){String assignee ="zhangsan";ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();// 任務查詢 需要獲取一個 TaskService 對象TaskService taskService = engine.getTaskService();// 根據流程的key和任務負責人 查詢任務// import org.activiti.engine.task.Task;List<Task> list = taskService.createTaskQuery().processDefinitionKey("evection").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());}
}
輸出結果
4 流程任務處理
任務負責人查詢出來了待辦的人,選擇任務進行處理,完成任務
/*** 流程任務的處理*/
@Test
public void test08(){ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();TaskService taskService = engine.getTaskService();List<Task> tasks = taskService.createTaskQuery().processDefinitionKey("evection").taskAssignee("zhangsan").list();//.singleResult();Task task = tasks.get(0);// 完成任務taskService.complete(task.getId());
}
zhangsan處理了這個操作后,流程就流轉到了 lisi處
然后就是不同的用戶登錄,然后查詢任務處理任務,直到任務流程走完。
5 流程定義的查詢
查詢流程相關的信息,包括流程的定義,流程的部署,流程定義的版本
/*** 查詢流程的定義*/
@Test
public void test09(){ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();RepositoryService repositoryService = engine.getRepositoryService();// 獲取一個 ProcessDefinitionQuery對象 用來查詢操作ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();List<ProcessDefinition> list = processDefinitionQuery.processDefinitionKey("evection").orderByProcessDefinitionVersion() // 安裝版本排序.desc() // 倒序.list();// 輸出流程定義的信息for (ProcessDefinition processDefinition : list) {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());}
}
輸出結果
6 流程的刪除
正常的工作流根本不會涉及到刪除操作
/*** 刪除流程*/
@Test
public void test10(){ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();RepositoryService repositoryService = engine.getRepositoryService();// 刪除流程定義,如果該流程定義已經有了流程實例啟動則刪除時報錯repositoryService.deleteDeployment("2501");// 設置為TRUE 級聯刪除流程定義,即使流程有實例啟動,也可以刪除,設置為false 非級聯刪除操作。//repositoryService.deleteDeployment("2501",true);
}
注意:項目開發中級聯刪除操作的權限一般只開發給超級管理員使用。
7 流程資源的下載
現在我們的流程資源文件已經上傳到了數據庫中,如果其他用戶想要查看這些資源,可以從數據庫中把這些資源下載到本地。
解決方案:
- jdbc對blob類型處理clob類型數據讀取出來就可以了。
- 使用activiti的api來實現操作。
使用activiti的api來操作我們需要添加commons-io的依賴
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version>
</dependency>
實現代碼
/*** 讀取數據庫中的資源文件*/
@Test
public void test11() throws Exception{// 1.得到ProcessEngine對象ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();// 2.獲取RepositoryService對象RepositoryService repositoryService = engine.getRepositoryService();// 3.得到查詢器ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().processDefinitionKey("evection").singleResult();// 4.獲取流程部署的idString deploymentId = definition.getDeploymentId();// 5.通過repositoryService對象的相關方法 來獲取圖片信息和bpmn信息// png圖片InputStream pngInput = repositoryService.getResourceAsStream(deploymentId, definition.getDiagramResourceName());// bpmn 文件的流InputStream bpmnInput = repositoryService.getResourceAsStream(deploymentId, definition.getResourceName());// 6.文件的保存File filePng = new File("d:/evection.png");File fileBpmn = new File("d:/evection.bpmn20.xml");OutputStream pngOut = Files.newOutputStream(filePng.toPath());OutputStream bpmnOut = Files.newOutputStream(fileBpmn.toPath());IOUtils.copy(pngInput,pngOut);IOUtils.copy(bpmnInput,bpmnOut);pngInput.close();pngOut.close();bpmnInput.close();bpmnOut.close();
}
8 流程歷史信息查看
即使流程定義已經被刪除了,流程執行的實例信息通過前面的分析,依然保存在Activiti的act_hi_*
的相關表結構中,所以我們還是可以查詢流程的執行的歷史信息,可以通過HistoryService來查看
/*** 流程歷史信息查看*/
@Test
public void test12(){ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();// 查看歷史信息我們需要通過 HistoryService來實現HistoryService historyService = engine.getHistoryService();// 獲取 ACT_HI_ACTINST 表的查詢對象HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();instanceQuery.processDefinitionId("evection:1:7504");instanceQuery.orderByHistoricActivityInstanceStartTime().desc();List<HistoricActivityInstance> list = instanceQuery.list();// 輸出查詢的結果for (HistoricActivityInstance hi : list) {System.out.println(hi.getActivityId());System.out.println(hi.getActivityName());System.out.println(hi.getActivityType());System.out.println(hi.getAssignee());System.out.println(hi.getProcessDefinitionId());System.out.println(hi.getProcessInstanceId());System.out.println("-----------------------");}
}
輸出結果