一 介紹
Activiti是一個工作流引擎,Activiti可以將業(yè)務(wù)系統(tǒng)中復(fù)雜的業(yè)務(wù)流程抽取出來,使用專門的建模語言BPMN2.0進(jìn)行定義,業(yè)務(wù)流程按照預(yù)先定義的流程進(jìn)行執(zhí)行,實現(xiàn)了系統(tǒng)的流程由Activiti進(jìn)行管理,減少業(yè)務(wù)系統(tǒng)由于流程變更進(jìn)行系統(tǒng)升級改造的工作量,Activiti流程就是數(shù)據(jù)庫表的創(chuàng)建、流程的部署、流程的啟動和各個階段任務(wù)的完成。
二 使用方法
2.1.在使用activiti之前,在pom文件中引入相關(guān)依賴。
<dependencies>
<!--activiti的核心包-->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring</artifactId>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-model</artifactId>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-converter</artifactId>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-json-converter</artifactId>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-layout</artifactId>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>org.activiti.cloud</groupId>
<artifactId>activiti-cloud-services-api</artifactId>
<version>7-201710-EA</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<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>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
<scope>provided</scope>
</dependency>
</dependencies>
2.2 編寫activiti.cfg.xml配置文件
activiti的引擎配置文件,包括:ProcessEngineConfiguration的定義、數(shù)據(jù)源定義、事務(wù)管理器等。其實就是一個Spring配置文件。
<?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">
<!--dbcp連接池-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/activiti"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
<property name="maxActive" value="3"/>
<property name="maxIdle" value="1"/>
</bean>
<!--在默認(rèn)方式下,bean的id固定為processEngineConfiguration-->
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<!--配置數(shù)據(jù)庫相關(guān)信息-->
<property name="dataSource" ref="dataSource"/>
<!--
activiti數(shù)據(jù)庫表處理策略
false(默認(rèn)值):檢查數(shù)據(jù)庫的版本和依賴庫的版本,如果不匹配就拋出異常
true:構(gòu)建流程引擎時,執(zhí)行檢查,如果需要就執(zhí)行更新。如果表不存在,就創(chuàng)建。
create-drop:構(gòu)建流程引擎時創(chuàng)建數(shù)據(jù)庫報表,關(guān)閉流程引擎時就刪除這些表。
drop-create:先刪除表再創(chuàng)建表。
create:構(gòu)建流程引擎時創(chuàng)建數(shù)據(jù)庫表,關(guān)閉流程引擎時不刪除這些表
-->
<property name="databaseSchemaUpdate" value="true"/>
<property name="asyncExecutorActivate" value="false"/>
<property name="mailServerHost" value="mail.my-corp.com"/>
<property name="mailServerPort" value="5025"/>
</bean>
</beans>
三 流程引擎配置類:
流程引擎配置類(ProcessEngineConfiguration),通過ProcessEngineConfiguration 可以創(chuàng)建工作流引擎 ProceccEngine。
四 工作流引擎的創(chuàng)建
工作流引擎的創(chuàng)建主要有兩種方式:默認(rèn)創(chuàng)建方式和一般創(chuàng)建方式
4.1 默認(rèn)創(chuàng)建方式
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
System.out.println(processEngine);
4.2 一般創(chuàng)建方式:
//使用自定義方式創(chuàng)建
ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
//獲取流程引擎對象:通過 ProcessEngineConfiguration 創(chuàng)建 ProcessEngine,此時會創(chuàng)建數(shù)據(jù)庫
ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
當(dāng)創(chuàng)建好工作流引擎后,對應(yīng)的數(shù)據(jù)庫中會自動生成25張數(shù)據(jù)庫表。
ACT_GE_PROPERTY中會先展示下一次流程的ID(next.dbid),并且在下一次流程部署的時候,對下一次流程的ID進(jìn)行賦值。
五 Activiti表說明
這里以表名的前綴進(jìn)行說明:
六 Service服務(wù)接口
Activiti中還有許多的Service服務(wù)接口。這些Service 是工作流引擎提供用于進(jìn)行工作流部署、執(zhí)行、管理的服務(wù)接口,我們可以使用這些接口操作服務(wù)對應(yīng)的數(shù)據(jù)表。
6.1 Service創(chuàng)建方式
通過ProcessEngine創(chuàng)建Service方式:
Runtimeservice runtimeService = processEngine.getRuntimeService();
RepositoryService repositoryService = processEngine.getRepositoryService();
TaskService taskService = processEngine.getTaskService();
6.2 Service總覽
6.2.1 RepositoryService
Activiti 的資源管理類,提供了管理和控制流程發(fā)布包和流程定義的操作。使用工作流建模工具設(shè)計的業(yè)務(wù)流程圖需要使用此service將流程定義文件的內(nèi)容部署到計算機。除了部署流程定義以外,還可以查詢引擎中的發(fā)布包和流程定義。
暫?;蚣せ畎l(fā)布包,對應(yīng)全部和特定流程定義。暫停意味著它們不能再執(zhí)行任何操作了,激活是對應(yīng)的反向操作。獲得多種資源,像是包含在發(fā)布包里的文件,或引擎自動生成的流程圖。獲得流程定義的pojo版本,可以用來通過java解析流程,而不必通過xml。
6.2.2 Runtimeservice
Activiti的流程運行管理類??梢詮倪@個服務(wù)類中獲取很多關(guān)于流程執(zhí)行相關(guān)的信息
6.2.3 Taskservice
Activiti的任務(wù)管理類。可以從這個類中獲取任務(wù)的信息。
6.2.4 Historyservice
Activiti的歷史管理類,可以查詢歷史信息,執(zhí)行流程時,引擎會保存很多數(shù)據(jù)(根據(jù)配置),比如流程實例啟動時間,任務(wù)的參與者,完成任務(wù)的時間,每個流程實例的執(zhí)行路徑,等等。這個服務(wù)主要通過查詢功能來獲得這些數(shù)據(jù)。
6.2.5 ManagementService
Activiti的引擎管理類,提供了對Activiti流程引擎的管理和維護(hù)功能,這些功能不在工作流驅(qū)動的應(yīng)用程序中使用,主要用于Activiti 系統(tǒng)的日常維護(hù)。
七 流程圖符號說明
7.1 BPMN插件
使用IDEA進(jìn)行開發(fā),建議下載一個插件。actiBPM插件,直接搜索下載。
7.2 流程符號、畫流程圖
流程符號:事件Event,活動Activity,網(wǎng)關(guān)Gateway,流向
使用流程設(shè)計器畫出流程圖步驟:
1.創(chuàng)建bpmn文件,在流程設(shè)計器使用流程符號來表達(dá)流程,指定流程的key,指定任務(wù)負(fù)責(zé)人。
2.生成png文件。
3.創(chuàng)建的bpmn文件要放在resourse下的bpmn文件夾下。
如下圖:
注意:當(dāng)前任務(wù)流程的ID不能是數(shù)字開頭。
找到本地的文件,打開
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" 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" xmlns:tns="http://www.activiti.org/test" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" expressionLanguage="http://www.w3.org/1999/XPath" id="m1611283406582" name="" targetNamespace="http://www.activiti.org/test" typeLanguage="http://www.w3.org/2001/XMLSchema">
<process id="myEvection" isClosed="false" isExecutable="true" name="出差申請" processType="None">
<startEvent id="_2" name="StartEvent"/>
<userTask activiti:assignee="zhangsan" activiti:exclusive="true" id="_3" name="創(chuàng)建出差申請"/>
<userTask activiti:assignee="jerry" activiti:exclusive="true" id="_4" name="經(jīng)理審批"/>
<userTask activiti:assignee="jack" activiti:exclusive="true" id="_5" name="總經(jīng)理審批"/>
<userTask activiti:assignee="rose" activiti:exclusive="true" id="_6" name="財務(wù)審批"/>
<endEvent id="_7" name="EndEvent"/>
<sequenceFlow id="_8" sourceRef="_2" targetRef="_3"/>
<sequenceFlow id="_9" sourceRef="_3" targetRef="_4"/>
<sequenceFlow id="_10" sourceRef="_4" targetRef="_5"/>
<sequenceFlow id="_11" sourceRef="_5" targetRef="_6"/>
<sequenceFlow id="_12" sourceRef="_6" targetRef="_7"/>
</process>
<bpmndi:BPMNDiagram documentation="background=#FFFFFF;count=1;horizontalcount=1;orientation=0;width=842.4;height=1195.2;imageableWidth=832.4;imageableHeight=1185.2;imageableX=5.0;imageableY=5.0" id="Diagram-_1" name="New Diagram">
<bpmndi:BPMNPlane bpmnElement="myEvection">
<bpmndi:BPMNShape bpmnElement="_2" id="Shape-_2">
<omgdc:Bounds height="32.0" width="32.0" x="185.0" y="0.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_3" id="Shape-_3">
<omgdc:Bounds height="55.0" width="85.0" x="160.0" y="85.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_4" id="Shape-_4">
<omgdc:Bounds height="55.0" width="85.0" x="160.0" y="185.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_5" id="Shape-_5">
<omgdc:Bounds height="55.0" width="85.0" x="160.0" y="285.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_6" id="Shape-_6">
<omgdc:Bounds height="55.0" width="85.0" x="160.0" y="390.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_7" id="Shape-_7">
<omgdc:Bounds height="32.0" width="32.0" x="185.0" y="475.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="_12" id="BPMNEdge__12" sourceElement="_6" targetElement="_7">
<omgdi:waypoint x="201.0" y="445.0"/>
<omgdi:waypoint x="201.0" y="475.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_8" id="BPMNEdge__8" sourceElement="_2" targetElement="_3">
<omgdi:waypoint x="201.0" y="32.0"/>
<omgdi:waypoint x="201.0" y="85.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_9" id="BPMNEdge__9" sourceElement="_3" targetElement="_4">
<omgdi:waypoint x="202.5" y="140.0"/>
<omgdi:waypoint x="202.5" y="185.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_11" id="BPMNEdge__11" sourceElement="_5" targetElement="_6">
<omgdi:waypoint x="202.5" y="340.0"/>
<omgdi:waypoint x="202.5" y="390.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_10" id="BPMNEdge__10" sourceElement="_4" targetElement="_5">
<omgdi:waypoint x="202.5" y="240.0"/>
<omgdi:waypoint x="202.5" y="285.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
八 流程的操作
使用 Activiti 提供的 API 把流程圖的內(nèi)容寫入到數(shù)據(jù)庫中,屬于資源操作類,使用 RepositoryService
單文件部署:把bpmn文件和png文件逐個處理
壓縮包部署:把bpmn文件和png文件打成壓縮包來處理
部署操作表:act_re_deployment、act_re_procdef、act_ge_bytearray
8.1 部署方式
8.1.1單文件部署
/
* 流程部署
*/
public void deployment() {
// 創(chuàng)建 ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 獲取 RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
// 使用 service 進(jìn)行流程的部署,定義一個流程的名字,把bpmn和png部署到數(shù)據(jù)中
Deployment deployment = repositoryService.createDeployment()
.name("出差申請流程") //流程圖標(biāo)的名字
.addClasspathResource("bpmn/evection.bpmn") //bpmn文件
.addClasspathResource("bpmn/evection.png") //bpmn文件生成的
.deploy();
// 輸出部署信息
System.out.println("流程部署ID:" + deployment.getId());
System.out.println("流程部署名字:" + deployment.getName());
}
8.1.2 壓縮文件部署
有時候我們會有多個流程,需要創(chuàng)建多個bpmn流程文件,這個時候想要同時部署,我們可以對bpmn文件進(jìn)行打包壓縮,使用Zip包進(jìn)行批量的部署
/
* 使用Zip包進(jìn)行批量的部署
*/
@Test
public void deployProcessByZip() {
// 獲取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 獲取 RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
// 流程部署
// 讀取資源包文件,構(gòu)造成 InputStream
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("bpmn/evection.zip");
// 使用 InputStream 構(gòu)造 ZipInputStream
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
// 使用壓縮包的流,進(jìn)行流程的部署
Deployment deploy = repositoryService.createDeployment()
.addZipInputStream(zipInputStream)
.deploy();
// 輸出
System.out.println("流程部署的ID:" + deploy.getId());
System.out.println("流程部署的名稱:" + deploy.getName());
}
操作的數(shù)據(jù)庫表:
act_ge_bytearray
act_ge_property
act_re_deployment
act_re_procdef
8.2 啟動流程實例
流程部署完成以后,需要啟動流程實例。使用 RuntimeService 根據(jù)流程定義的 key進(jìn)行啟動。
核心代碼:
/
* 啟動流程
*/
public void starProcess() {
// 創(chuàng)建 ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 獲取 RunTimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
// 根據(jù)流程定義的ID啟動流程
ProcessInstance instance = runtimeService.startProcessInstanceByKey("myEvection");
// 輸出內(nèi)容
System.out.println("流程定義ID:" + instance.getProcessDefinitionId());
System.out.println("流程實例的ID:" + instance.getId());
System.out.println("當(dāng)前活動的ID:" + instance.getActivityId());
}
8.3 任務(wù)查詢:
使用 TaskService ,根據(jù)流程定義的 key ,任務(wù)負(fù)責(zé)人來進(jìn)行查詢
/
* 查詢個人待執(zhí)行的任務(wù)
*/
@Test
public void findPersonalTaskList() {
// 獲取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 獲取TaskService
TaskService taskService = processEngine.getTaskService();
// 根據(jù)流程的key和任務(wù)的負(fù)責(zé)人去查詢?nèi)蝿?wù)
List<Task> taskList = taskService.createTaskQuery()
.processDefinitionKey("myEvection") // 流程的key
.includeProcessVariables()
.taskAssignee("zhangsan") // 要查詢的負(fù)責(zé)人
.list();
// 輸出
for (Task task : taskList) {
System.out.println("流程實例的ID:" + task.getProcessInstanceId());
System.out.println("任務(wù)的ID:" + task.getId());
System.out.println("任務(wù)的負(fù)責(zé)人:" + task.getAssignee());
System.out.println("任務(wù)的名稱:" + task.getName());
}
}
8.4 任務(wù)完成
使用 TaskService ,用任務(wù) ID 直接完成任務(wù)。
/
* 完成個人任務(wù)
*/
@Test
public void completTask() {
String key = "testCandidiate";
String assignee = "張三1"; //任務(wù)的負(fù)責(zé)人
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
Task task = taskService.createTaskQuery()
.processDefinitionKey(key)
.taskAssignee(assignee)
.singleResult();
if (task != null) {
taskService.complete(task.getId());
}
}
8.5 流程實例的掛起和激活
8.5.1 全部流程實例的掛起和激活
/
* 全部流程實例的掛起和激活
*/
@Test
public void suspendAllProcessInstance() {
// 1.獲取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2.獲取 RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
// 3.查詢流程定義
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("myEvection")
.singleResult();
// 4.獲取當(dāng)前流程定義的實例是否都是掛起狀態(tài)
boolean flag = processDefinition.isSuspended();
// 5.獲取流程定義的ID
String id = processDefinition.getId();
// 6.判斷是否掛起狀態(tài)。是:改為激活;否:改為掛起
if (flag) {
// 改為激活. 參數(shù)1:流程定義的ID,參數(shù)2:是否激活,參數(shù)3:激活時間
repositoryService.activateProcessDefinitionById(id, true, null);
System.out.println("流程定義ID:" + id + "已激活");
} else {
// 改為掛起. 參數(shù)1:流程定義的ID;參數(shù)2:是否掛起;參數(shù)3:掛起時間
repositoryService.suspendProcessDefinitionById(id, true, null);
System.out.println("流程定義ID:" + id + "已掛起");
}
}
8.5.2 單個流程實例的掛起和激活
/
* 單個流程實例的掛起和激活
*/
@Test
public void suspendSingleProcessInstance() {
// 1.獲取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2.獲取 RuntimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
// 3.通過 RuntimeService 獲取流程實例對象
ProcessInstance instance = runtimeService.createProcessInstanceQuery()
.processInstanceId("17501")
.singleResult();
// 4.得到當(dāng)前流程實例的暫停狀態(tài)
boolean flag = instance.isSuspended();
// 5.獲取流程實例的ID
String instanceId = instance.getId();
// 6.判斷是否暫停。是:改為激活;否:改為暫停
if (flag) {
runtimeService.activateProcessInstanceById(instanceId);
System.out.println("流程實例ID:" + instanceId + "已激活");
} else {
runtimeService.suspendProcessInstanceById(instanceId);
System.out.println("流程實例ID:" + instanceId + "已暫停");
}
}
注意:流程實例在掛起的狀態(tài)下是無法進(jìn)行下一步操作的。
九 流程變量
我們在使用流程變量的時候。如果我們將一個對象存儲到一個流程變量中,那么這個對象需要實現(xiàn)Serializable接口。
/
* 出差申請中的流程變量對象
*/
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Evection implements Serializable {
private Long id; //主鍵ID
private Integer days; //出差天數(shù)
private String evectionName; //出差單名字
private Date startTime; //出差開始時間
private Date endTime; //出差結(jié)束時間
private String address; //目的地
private String reason; //出差原因
}
流程變量的作用域:
整個流程實例、任務(wù)、執(zhí)行實例。
默認(rèn):整個流程實例。
9.1 使用方法
在屬性上使用UEL表達(dá)式 ${assignee},assignee就是一個流程變量的名稱。
在連線上使用UEL表達(dá)式 ${days<=3},days就是一個流程變量名稱,返回結(jié)果為true或者false。
9.2 Activiti有很多種方式設(shè)置流程變量,這里簡單介紹兩種:
9.2.1 啟動流程時設(shè)置流程變量
/
* 啟動流程
*/
@Test
public void startProcess() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
// 流程變量map
Map<String, Object> map = new HashMap<>();
// 設(shè)置流程變量
Evection evection = new Evection();
evection.setDays(2);
// 把流程變量的pojo放入map
map.put("evection", evection);
map.put("assignee0", "張三");
map.put("assignee1", "李經(jīng)理");
map.put("assignee2", "王財務(wù)");
map.put("assignee3", "趙總經(jīng)理");
runtimeService.startProcessInstanceByKey("myProcess_1", map);
}
9.1.2 任務(wù)辦理時設(shè)置
/
* 完成任務(wù)
*/
@Test
public void completTask() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
Evection evection = new Evection();
evection.setDays(2);
Map<String, Object> map = new HashMap<>();
map.put("evection", evection);
Task task = taskService.createTaskQuery()
.processDefinitionKey("myProcess_2")
.taskAssignee("王財務(wù)0")
.singleResult();
if (task != null) {
String taskId = task.getId();
// 完成任務(wù)
taskService.complete(taskId, map);
}
}
十 網(wǎng)關(guān)
用來控制流程的走向
10.1 排他網(wǎng)關(guān)——ExclusiveGateway
用來在流程中實現(xiàn)決策,當(dāng)流程執(zhí)行到這個網(wǎng)關(guān),所有的分支都會判斷條件是否為true,如果為true,則執(zhí)行該分支。
注意:排他網(wǎng)關(guān)只會選擇一個作為true的分支執(zhí)行,如果有兩個分支都為true,排他網(wǎng)關(guān)會選擇ID值比較小的一條分支去執(zhí)行。
如果從排他網(wǎng)關(guān)出去的流程所有的條件都不滿足,則會拋出異常。
10.2 并行網(wǎng)關(guān)——ParallelGateway
并行網(wǎng)關(guān),允許流程分成多條分支,也可以把多分支匯聚到一起,并行網(wǎng)關(guān)的功能是基于進(jìn)入和外出順序流的:
1 fork分支:并行后的所有外出順序流,為每個順序流都創(chuàng)建一個并發(fā)分支
2 join匯聚:所有到達(dá)并行網(wǎng)關(guān),在此等待的分支,直到所有進(jìn)入順序流的分支都到達(dá)以后,流程就會通過匯聚網(wǎng)關(guān)。
注意:如果同一個并行網(wǎng)關(guān)有多個進(jìn)入和多個外出順序流,它就同時具有分支和匯聚功能,這時,網(wǎng)關(guān)會先匯聚所有進(jìn)入的順序流,然后再切分成多個并行分支。
與其他網(wǎng)關(guān)的主要區(qū)別是:并行網(wǎng)關(guān)不會解析條件,即使順序流中定義了條件,也會被忽略。
并行網(wǎng)關(guān)需要所有分支的全部運行完了,才會匯聚,繼續(xù)向下執(zhí)行。
10.3 包含網(wǎng)關(guān)——InclusiveGateway
包含網(wǎng)關(guān)可以看成是排他網(wǎng)關(guān)和并行網(wǎng)關(guān)的結(jié)合體,和排他網(wǎng)關(guān)一樣,可以在外出順序流上定義條件,包含網(wǎng)關(guān)會解析它們,但是主要的區(qū)別是:包含網(wǎng)關(guān)可以選擇多于一條順序流,這和并行網(wǎng)關(guān)一樣。
包含網(wǎng)關(guān)的功能是基于進(jìn)入和外出順序流的。
分支:所有外出順序流的條件都會被解析,結(jié)果為true的順序流會以并行方式繼續(xù)執(zhí)行,會為每一個順序流創(chuàng)建一個分支。
匯聚:所有并行分支到達(dá)包含網(wǎng)關(guān),會進(jìn)入等待狀態(tài),直到每個包含流程token的進(jìn)入順序流的分支都到達(dá)。這是和并行網(wǎng)關(guān)最大的不同。文章來源:http://www.zghlxwxcb.cn/news/detail-412401.html
10.4 事件網(wǎng)關(guān)——EventGateway
Activiti和SpringBoot的整合開發(fā)
配置文件文章來源地址http://www.zghlxwxcb.cn/news/detail-412401.html
spring:
application:
name: actspringboot
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/actspring?useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true&serverTimezone=UTC
username: root
password: root
activiti:
# false:默認(rèn)值。activiti在啟動時,會對比數(shù)據(jù)庫表中保存的版本。如果沒有表或者版本不匹配,將拋出異常
# true:activiti會對數(shù)據(jù)庫中所有表進(jìn)行更新操作,如果表不存在,則會自動創(chuàng)建
# create_drop:在activiti啟動時創(chuàng)建表,在關(guān)閉時刪除表(必須手動關(guān)閉引擎,才能刪除表)
# drop-create:在activiti啟動時刪除原來的舊表,然后再創(chuàng)建新表(不需要手動關(guān)閉引擎)
# 線上一般使用false,開發(fā)中使用true
database-schema-update: true
# 自動部署驗證設(shè)置:true-開啟(默認(rèn))、false-關(guān)閉
check-process-definitions: false
# 開啟歷史表
db-history-used: true
# 歷史記錄存儲等級
history-level: full
server:
port: 8082
到了這里,關(guān)于Spring Boot + Activiti 結(jié)合,實現(xiàn)工作流的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!