Activiti7工作流的使用
阿新 • • 發佈:2020-08-02
Activiti服務架構
概述
activiti-cfg.xml
- activiti-cfg.xml是activiti的引擎配置檔案,包括:ProcessEngineConfiguration的定義、資料來源的定義、事務管理器等,此檔案其實就是一個Spring配置檔案,下面是一個基本的配置只配置了ProcessEngineConfiguration和資料來源。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 配置資料來源 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> <property name="username" value="root"/> <property name="url" value="jdbc:mysql://192.168.134.100:3306/activiti?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true"/> <property name="password" value="123456"/> <property name="maxActive" value="3"/> <property name="maxIdle" value="1"/> </bean> <!-- Activiti單獨執行的ProcessEngine配置 --> <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"> <!-- 資料來源 --> <property name="dataSource" ref="dataSource"/> <!-- activiti資料庫表處理策略 false(預設值):檢查資料庫的版本和依賴庫的版本,如果不匹配就丟擲異常 true:構建流程引擎時,執行檢查,如果需要就執行更新。如果表不存在,就建立。 create-drop:構建流程引擎時建立資料庫報表,關閉流程引擎時就刪除這些表。 drop-create:先刪除表再建立表。 create:構建流程引擎時建立資料庫表,關閉流程引擎時不刪除這些表 --> <property name="databaseSchemaUpdate" value="true"/> </bean> </beans>
ProcessEngineConfiguration
概述
- 流程引擎的配置類,通過ProcessEngineConfiguration可以建立工作流引擎ProcessEngine,常用的兩種方法如下:
StandaloneProcessEngineConfiguration
-
通過org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration,Activiti可以單獨執行,使用它建立的ProcessEngine,Activiti會自己處理事務。
-
配置檔案方式:
- 通常在activiti-cfg.xml配置檔案中定義一個id為processEngineConfiguration的Bean,這裡會使用Spring的依賴注入來構建引擎。
<!-- Activiti單獨執行的ProcessEngine配置 --> <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"> <!-- 資料來源 --> <property name="dataSource" ref="dataSource"/> <!-- activiti資料庫表處理策略 false(預設值):檢查資料庫的版本和依賴庫的版本,如果不匹配就丟擲異常 true:構建流程引擎時,執行檢查,如果需要就執行更新。如果表不存在,就建立。 create-drop:構建流程引擎時建立資料庫報表,關閉流程引擎時就刪除這些表。 drop-create:先刪除表再建立表。 create:構建流程引擎時建立資料庫表,關閉流程引擎時不刪除這些表 --> <property name="databaseSchemaUpdate" value="true"/> </bean>
SpringProcessEngineConfiguration
- 通過org.activiti.spring.SpringProcessEngineConfiguration和Spring整合。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns="http://www.springframework.org/schema/beans" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置資料來源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="username" value="root"/>
<property name="url"
value="jdbc:mysql://192.168.134.100:3306/activiti?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true"/>
<property name="password" value="123456"/>
<property name="maxActive" value="3"/>
<property name="maxIdle" value="1"/>
</bean>
<!-- 工作流引擎配置bean -->
<bean id="processEngineConfiguration"
class="org.activiti.spring.SpringProcessEngineConfiguration">
<!-- 資料來源 -->
<property name="dataSource" ref="dataSource"/>
<!-- 使用spring事務管理器 -->
<property name="transactionManager" ref="transactionManager"/>
<!-- 資料庫策略 -->
<property name="databaseSchemaUpdate" value="drop-create"/>
</bean>
<!-- 流程引擎 -->
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration"
ref="processEngineConfiguration"/>
</bean>
<!-- 資源服務service -->
<bean id="repositoryService" factory-bean="processEngine"
factory-method="getRepositoryService" />
<!-- 流程執行service -->
<bean id="runtimeService" factory-bean="processEngine"
factory-method="getRuntimeService" />
<!-- 任務管理service -->
<bean id="taskService" factory-bean="processEngine"
factory-method="getTaskService" />
<!-- 歷史管理service -->
<bean id="historyService" factory-bean="processEngine"
factory-method="getHistoryService" />
<!-- 引擎管理service -->
<bean id="managementService" factory-bean="processEngine"
factory-method="getManagementService" />
<!-- 事務管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 傳播行為 -->
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 切面,根據具體專案修改切點配置 -->
<aop:config proxy-target-class="true">
<aop:advisor advice-ref="txAdvice"
pointcut="execution(* com.sunxiaping.*.service.impl.*.*(..))" />
</aop:config>
</beans>
建立ProcessEngineConfiguration
- 下面的方法:要求activiti-cfg.xml中必須由一個processEngineConfiguration的Bean的id。
public static ProcessEngineConfiguration createProcessEngineConfigurationFromResource(String resource) {
return createProcessEngineConfigurationFromResource(resource, "processEngineConfiguration");
}
- 下面的方法,可以更改Bean的id。
public static ProcessEngineConfiguration createProcessEngineConfigurationFromResource(String resource, String beanName) {
return BeansConfigurationHelper.parseProcessEngineConfigurationFromResource(resource, beanName);
}
ProcessEngine
- 工作流引擎,相當於一個門面介面,通過ProcessEngineConfiguration建立ProcessEngine,通過ProcessEngine建立各個Service介面。
一般建立方式
- 示例:
package com.sunxiaping;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-07-31 6:41
*/
public class ActivitiTest {
public static void main(String[] args) {
//建立ProcessEngineConfiguration物件
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
//建立ProcessEngine物件
ProcessEngine processEngine = configuration.buildProcessEngine();
System.out.println("processEngine = " + processEngine);
}
}
簡單建立方式
- 將activiti.cfg.xml檔名以及路徑固定,且activiti.cfg.xml檔案中有processEngineConfiguration的配置,那麼可以使用如下程式碼建立ProcessEngine。
package com.sunxiaping;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-07-31 6:41
*/
public class ActivitiTest {
public static void main(String[] args) {
//該方法有限制
//①Activiti的配置檔名必須為activiti.cfg.xml
//②Bean的id必須是processEngineConfiguration
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
System.out.println("processEngine = " + processEngine);
}
}
Service
Service的建立方式
-
通過ProcessEngine建立Service,Service是工作流引擎提供用於進行工作流部署、指定、管理的服務介面。
-
建立方式如下:
package com.sunxiaping;
import org.activiti.engine.*;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-07-31 11:55
*/
public class ActivitiTest {
public static void main(String[] args) {
//建立ProcessEngineConfiguration物件
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
//建立ProcessEngine物件
ProcessEngine processEngine = configuration.buildProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
RuntimeService runtimeService = processEngine.getRuntimeService();
TaskService taskService = processEngine.getTaskService();
HistoryService historyService = processEngine.getHistoryService();
ManagementService managementService = processEngine.getManagementService();
System.out.println("repositoryService = " + repositoryService);
System.out.println("runtimeService = " + runtimeService);
System.out.println("taskService = " + taskService);
System.out.println("historyService = " + historyService);
System.out.println("managementService = " + managementService);
}
}
Service總覽
Service介面 | 說明 |
---|---|
RepositoryService | Activiti的資源管理介面 |
RuntimeService | Activiti的流程執行管理介面 |
TaskService | Activiti的任務管理介面 |
HistoryService | Activiti的歷史管理介面 |
ManagementService | Activiti的引擎管理介面 |
RepositoryService
- RepositoryService,是Activiti的資源管理介面,提供了管理和控制流程釋出包和流程定義的操作。使用工作流建模工具設計的業務流程圖需要使用此Service將流程定義檔案的內容部署到計算機中。
- 除了流程部署定義以外還可以做如下的操作:
- 1️⃣查詢引擎中的釋出包和流程定義。
- 2️⃣暫停或啟用釋出包以及對應全部和特定流程定義。暫停意味著它們不能再在執行任務操作了,啟用是對應的反向操作。
- 3️⃣獲取多種資源,像包含在釋出包中的檔案獲引擎自動生成的流程圖。
- 4️⃣獲取流程定義的POJO,可以用解析流程,而不必通過XML。
RuntimeService
- RuntimeService是Activiti的流程執行管理介面,可以從這個介面中獲取很多關於流程執行相關的資訊。
TaskService
- TaskService是Activiti的任務管理介面,可以從這個介面中獲取任務的資訊。
HistoryService
- HistoryService是Activiti的歷史管理類,可以查詢歷史資訊,執行流程時,引擎會包含很多資料(根據配置),比如流程例項啟動時間,任務的參與者,完成任務的時間,每個流程例項的執行路徑,等等。
ManagementService
- ManagementService是Activiti的引擎管理介面,提供了對Activiti流程引擎的管理和維護功能,這些功能不在工作流驅動的應用程式中使用,主要用於Activiti系統的日常維護。
Activiti入門體驗
流程定義
畫板
-
在IDEA中安裝對應的Activiti-Designer(Activiti設計器)外掛即可使用,畫板中包括以下結點:
- Connection--連線。
- Event--事件。
- Task--任務。
- Gateway--閘道器。
- Container--容器。
- Boundary event--邊界事件。
- Intermediate event--中間事件。
-
流程圖設計完畢儲存生成.bpmn檔案。
-
本人此時使用的IDEA版本是2020.2,而IDEA中的Activiti設計器外掛actiBPM到此時位置已停止更新了。
- 本人只能使用Eclipse畫流程圖。
- Eclipse需要安裝Activiti外掛,略。
繪製流程
指定流程定義key
- 流程定義key即流程定義的標識。
建議:相同的業務流程,流程定義的key名字定義一樣。如果需要建立新的業務流程,則使用新的key。
指定任務負責人
- 為每個任務結點指定負責人,如新增請假單的負責人是張三。
部署流程定義
- 將剛才生成的holiday.bpmn和holiday.png拷貝到專案的resources目錄下。
- 示例:使用RepositoryService部署流程定義
package com.sunxiaping;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.junit.Test;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-07-31 11:55
*/
public class ActivitiDeploymentTest {
/**
* 部署流程定義:將下面程式碼中指定的bpmn檔案和png檔案儲存到Activiti資料庫中
*
* act_re_deployment 部署資訊
* act_re_procdef 流程定義的一些資訊
* act_ge_bytearray 流程定義bpmn檔案和png檔案
*/
@Test
public void test() {
//建立ProcessEngineConfiguration物件
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
//獲取RepositoryService物件
RepositoryService repositoryService = processEngine.getRepositoryService();
//進行部署
Deployment deployment = repositoryService.createDeployment()
.addClasspathResource("diagram/holiday.bpmn") //新增bpmn資源
.addClasspathResource("diagram/holiday.png")
.name("請假申請流程")
.deploy(); //部署
//輸出部署的一些資訊
String id = deployment.getId();
System.out.println("流程部署id = " + id);
String name = deployment.getName();
System.out.println("流程部署名稱 = " + name);
}
}
啟動一個流程例項
- 流程定義部署在Activiti中之後就可以通過工作流管理業務流程了。
- 針對該流程,啟動一個流程表示發起一個新的請假申請單,這就相當於Java類和Java物件的關係,類定義好之後需要new建立一個物件使用,當然,也可以new多個物件。
- 對於請假申請流程,張三發起一個請假申請單需要啟動一個流程例項,李四發起一個請求申請單也需要啟動一個流程例項。
關係:
流程定義(BPMN檔案)-->流程部署(Activiti的三張表)。
流程例項-->啟動流程例項。
類比:
流程定義類似於Java中的類,流程例項類似於Java中的一個例項(物件),所以一個流程定義key對應多個不同的流程例項。
- 示例:
package com.sunxiaping;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.ProcessInstance;
import org.junit.Test;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-08-01 14:35
*/
public class ActivitiStartProcessInstanceTest {
/**
* act_hi_actinst 活動例項
* act_hi_identitylink 參與者資訊
* act_hi_procinst 流程例項
* act_hi_taskinst 任務例項
* act_ru_execution 執行表
* act_ru_identitylink 參與者資訊
* act_ru_task 任務表
*/
@Test
public void test() {
//建立ProcessEngineConfiguration物件
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
//獲取RuntimeService物件
RuntimeService runtimeService = processEngine.getRuntimeService();
//根據流程定義的key啟動流程例項
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holiday");
//獲取流程例項的相關資訊
String processDefinitionId = processInstance.getProcessDefinitionId();
System.out.println("流程定義的id = " + processDefinitionId);
String deploymentId = processInstance.getDeploymentId();
System.out.println("流程部署的id = " + deploymentId);
String id = processInstance.getId();
System.out.println("流程例項的id = " + id);
String activityId = processInstance.getActivityId();
System.out.println("當前活動的id = " + activityId);
}
}
任務查詢
-
流程啟動後,各個任務的負責人就可以查詢自己當前需要處理的任務,查詢出來的任務都是該使用者的待辦任務。
-
示例:
package com.sunxiaping;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.junit.Test;
import java.util.List;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-08-01 15:00
*/
public class ActivitiTaskTest {
/**
* act_ru_task
*/
@Test
public void test() {
//任務負責人
String assignee = "張三";
//建立ProcessEngineConfiguration物件
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
//獲取TaskService物件
TaskService taskService = processEngine.getTaskService();
//查詢任務列表,根據流程定義的key和任務負責人
List<Task> taskList = taskService.createTaskQuery().processDefinitionKey("holiday").taskAssignee(assignee).list();
//遍歷任務列表
for (Task task : taskList) {
String processDefinitionId = task.getProcessDefinitionId();
System.out.println("流程定義id = " + processDefinitionId);
String processInstanceId = task.getProcessInstanceId();
System.out.println("流程例項id = " + processInstanceId);
String assignee1 = task.getAssignee();
System.out.println("任務負責人 = " + assignee1);
String id = task.getId();
System.out.println("任務id = " + id);
String name = task.getName();
System.out.println("任務名稱 = " + name);
}
}
}
任務處理
-
任務負責人查詢待辦任務,選擇任務進行處理,完成任務。
-
示例:
package com.sunxiaping;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.junit.Test;
import java.util.List;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-08-01 15:20
*/
public class ActivitiTaskCompleteTest {
/**
* act_hi_actinst 活動例項
* act_hi_identitylink 參與者資訊
* act_hi_taskinst 任務例項
* act_ru_execution 執行表
* act_ru_identitylink 參與者資訊
* act_ru_task 任務表
*/
@Test
public void test() {
//任務負責人
String assignee = "張三";
//建立ProcessEngineConfiguration物件
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
//獲取TaskService物件
TaskService taskService = processEngine.getTaskService();
//查詢任務列表,根據流程定義的key和任務負責人
List<Task> taskList = taskService.createTaskQuery().processDefinitionKey("holiday").taskAssignee(assignee).list();
//遍歷任務列表
for (Task task : taskList) {
String id = task.getId();
//完成任務
taskService.complete(id);
}
}
}
流程定義
流程定義概述
什麼是流程定義?
- 流程定義是按照BPMN2.0標準去描述業務流程,通常使用Activiti-explorer(Activiti控制檯)或Activiti-eclipse-designer(Activiti的eclipse設計器)外掛對業務流程進行建模,這兩種方式都遵循BPMN2.0標準。
- 如果使用Activiti-eclipse-designer外掛完成業務流程建模。可以生成兩個檔案:.bpmn和.png檔案。
.bpmn檔案
- .bpmn檔案其實就是XML檔案。
<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="holiday" name="請假申請流程" isExecutable="true">
<startEvent id="startevent2" name="開始"/>
<userTask id="usertask1" name="填寫請假申請單" activiti:assignee="張三"/>
<sequenceFlow id="flow1" sourceRef="startevent2" targetRef="usertask1"/>
<userTask id="usertask2" name="部門經理審批" activiti:assignee="李四"/>
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"/>
<userTask id="usertask3" name="總經理審批" activiti:assignee="王五"/>
<sequenceFlow id="flow3" sourceRef="usertask2" targetRef="usertask3"/>
<endEvent id="endevent1" name="結束"/>
<sequenceFlow id="flow4" sourceRef="usertask3" targetRef="endevent1"/>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_holiday">
<bpmndi:BPMNPlane bpmnElement="holiday" id="BPMNPlane_holiday">
<bpmndi:BPMNShape bpmnElement="startevent2" id="BPMNShape_startevent2">
<omgdc:Bounds height="35.0" width="35.0" x="100.0" y="160.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
<omgdc:Bounds height="55.0" width="105.0" x="180.0" y="150.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
<omgdc:Bounds height="55.0" width="105.0" x="330.0" y="150.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3">
<omgdc:Bounds height="55.0" width="105.0" x="480.0" y="150.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="630.0" y="160.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="135.0" y="177.0"/>
<omgdi:waypoint x="180.0" y="177.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="285.0" y="177.0"/>
<omgdi:waypoint x="330.0" y="177.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="435.0" y="177.0"/>
<omgdi:waypoint x="480.0" y="177.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
<omgdi:waypoint x="585.0" y="177.0"/>
<omgdi:waypoint x="630.0" y="177.0"/>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
- .bpmn檔案的根節點是definitions節點。這個元素中,可以定義多個流程定義(建議每個檔案只包含一個流程定義,可以簡化開發過程中的維護難度)。注意,definitions元素最少也要包含xmlns和targetNamespace的宣告。targetNamespace可以是任何值,它用來對流程例項進行分類。
- 流程定義部分:定義了流程每個結點的描述和結點之間的流程流轉。
- 流程佈局定義:定義流程每個結點在流程圖上的位置座標等資訊。
.png圖片檔案
- 如果是在Eclipse中,需要進行如下的配置:
流程定義部署
什麼是流程定義部署
- 將生成的流程定義部署到Activiti的資料庫中,這就是流程定義部署,通過呼叫Activiti的API將流程定義的bpmn和png兩個檔案一個一個新增部署到Activiti中,也可以將兩個檔案打成zip包進行部署。
單個檔案部署方式
-
分別將bpmn檔案和png圖片檔案部署。
-
示例:
package com.sunxiaping;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.junit.Test;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-07-31 11:55
*/
public class ActivitiDeploymentTest {
/**
* 部署流程定義:將下面程式碼中指定的bpmn檔案和png檔案儲存到Activiti資料庫中
*
* act_re_deployment 部署資訊
* act_re_procdef 流程定義的一些資訊
* act_ge_bytearray 流程定義bpmn檔案和png檔案
*/
@Test
public void test() {
//建立ProcessEngineConfiguration物件
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
//獲取RepositoryService物件
RepositoryService repositoryService = processEngine.getRepositoryService();
//進行部署
Deployment deployment = repositoryService.createDeployment()
.addClasspathResource("diagram/holiday.bpmn") //新增bpmn資源
.addClasspathResource("diagram/holiday.png")
.name("請假申請流程")
.deploy(); //部署
//輸出部署的一些資訊
String id = deployment.getId();
System.out.println("流程部署id = " + id);
String name = deployment.getName();
System.out.println("流程部署名稱 = " + name);
}
}
壓縮包部署方式
- 將.bpmn檔案和.png圖片壓縮成一個zip包。
- 示例:
package com.sunxiaping;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.junit.Test;
import java.io.InputStream;
import java.util.zip.ZipInputStream;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-07-31 11:55
*/
public class ActivitiZipDeploymentTest {
/**
* 部署流程定義:將下面程式碼中指定的bpmn檔案和png檔案儲存到Activiti資料庫中
*
* act_re_deployment 部署資訊
* act_re_procdef 流程定義的一些資訊
* act_ge_bytearray 流程定義bpmn檔案和png檔案
*/
@Test
public void test() {
//建立ProcessEngineConfiguration物件
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
//獲取RepositoryService物件
RepositoryService repositoryService = processEngine.getRepositoryService();
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("diagram/holiday.zip");
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
//進行部署
Deployment deployment = repositoryService.createDeployment()
.addZipInputStream(zipInputStream)
.name("請假申請流程")
.deploy(); //部署
//輸出部署的一些資訊
String id = deployment.getId();
System.out.println("流程部署id = " + id);
String name = deployment.getName();
System.out.println("流程部署名稱 = " + name);
}
}
操作資料表
- 流程定義部署後,會操作三張表:
act_re_deployment
、act_re_procdef
和act_ge_bytearray
。 act_re_deployment
是流程定義部署表,記錄流程部署資訊。act_re_procdef
是流程定義表,記錄流程定義資訊。act_ge_bytearray
是資源表,將.bpmn檔案和.png圖片存入到這個表。
說明:
act_re_deployment
和act_re_procdef
是一對多的關係,一次部署在流程部署表生成一條記錄,但一次流程部署可以部署多個流程定義,每個流程定義在流程定義表生成一條記錄。每一個流程定義在act_ge_bytearray
會存在兩個資源記錄.bpmn檔案和.png圖片。建議:
- 一次部署一個流程,這樣部署表和流程定義表示一對一的關係,方便讀取流程部署和流程定義資訊。
流程定義查詢
- 示例:
package com.sunxiaping;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.junit.Test;
import java.util.List;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-08-01 21:24
*/
public class ActivitiProcessDefinitionQueryTest {
/**
* 查詢流程定義資訊
*/
@Test
public void test() {
//建立ProcessEngineConfiguration物件
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
//獲取RepositoryService物件
RepositoryService repositoryService = processEngine.getRepositoryService();
//得到ProcessDefinitionQuery物件
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
//設定條件,並查詢出當前的所有流程定義
List<ProcessDefinition> processDefinitionList = processDefinitionQuery.processDefinitionKey("holiday")
.orderByProcessDefinitionVersion()
.desc()
.list();
//輸出流程定義資訊
for (ProcessDefinition processDefinition : processDefinitionList) {
System.out.println("流程定義的id = " + processDefinition.getId());
System.out.println("流程定義的name = " + processDefinition.getName());
System.out.println("流程定義的key = " + processDefinition.getKey());
System.out.println("流程定義的version = " + processDefinition.getVersion());
}
}
}
流程定義刪除
- 示例:
package com.sunxiaping;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RepositoryService;
import org.junit.Test;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-08-01 21:13
*/
public class ActivitiDeleteProcessDefinitionTest {
/**
* 刪除已經部署的流程定義
*
* 注意事項:
* ①當我們正在執行的這一套流程沒有結束,此時如果要刪除流程定義資訊就會失敗(呼叫void deleteDeployment(String deploymentId)方法)。
* ②當我們正在執行的這一套流程沒有結束,此時如果要強制刪除流程定義資訊,需要呼叫void deleteDeployment(String deploymentId, boolean cascade)這個方式,將cascade設定為true。
*/
@Test
public void test() {
//建立ProcessEngineConfiguration物件
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
//獲取RepositoryService物件
RepositoryService repositoryService = processEngine.getRepositoryService();
//刪除已經部署的流程定義
String deploymentId = "1";
repositoryService.deleteDeployment(deploymentId);
}
}
流程定義資源查詢
- 示例:通過查詢流程定義物件獲取流程定義資源,即bpmn和png
package com.sunxiaping;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.junit.Test;
import org.springframework.util.FileCopyUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-08-02 10:22
*/
public class ActivitiResourceTest {
@Test
public void test() throws IOException {
//建立ProcessEngineConfiguration物件
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
//獲取RepositoryService物件
RepositoryService repositoryService = processEngine.getRepositoryService();
//獲取ProcessDefinitionQuery物件
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
//設定查詢條件,執行查詢操作
List<ProcessDefinition> processDefinitionList = processDefinitionQuery.processDefinitionKey("holiday").orderByProcessDefinitionVersion().desc().list();
//遍歷查詢結果
for (ProcessDefinition processDefinition : processDefinitionList) {
//獲取資源名稱,即png圖片的名稱
String resourceName = processDefinition.getResourceName();
//獲取圖表資源,即bpmn圖片的名稱
String diagramResourceName = processDefinition.getDiagramResourceName();
//獲取資源的輸入流,即png圖片的輸入流
InputStream resourceNameInputStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resourceName);
InputStream diagramResourceNameInputStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), diagramResourceName);
String resourcePath = "d:" + File.separator + resourceName;
File file = new File(resourcePath);
if (!file.exists()) {
file.getParentFile().mkdirs();
}
String diagramResourcePath = "d:" + File.separator + diagramResourceName;
file = new File(diagramResourcePath);
if (!file.exists()) {
file.getParentFile().mkdirs();
}
//複製檔案
FileCopyUtils.copy(resourceNameInputStream, new FileOutputStream(resourcePath));
FileCopyUtils.copy(diagramResourceNameInputStream, new FileOutputStream(diagramResourcePath));
}
}
}
流程歷史資訊查詢
- 示例:
package com.sunxiaping;
import org.activiti.engine.HistoryService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricActivityInstanceQuery;
import org.junit.Test;
import java.util.List;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-08-01 21:13
*/
public class ActivitiHistoryTest {
@Test
public void test() {
//建立ProcessEngineConfiguration物件
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
//獲取ProcessEngine物件
ProcessEngine processEngine = configuration.buildProcessEngine();
//獲取HistoryService物件
HistoryService historyService = processEngine.getHistoryService();
//獲取HistoricActivityInstanceQuery查詢物件
HistoricActivityInstanceQuery historicActivityInstanceQuery = historyService.createHistoricActivityInstanceQuery();
List<HistoricActivityInstance> historicActivityInstanceList = historicActivityInstanceQuery.list();
for (HistoricActivityInstance historicActivityInstance : historicActivityInstanceList) {
String activityId = historicActivityInstance.getActivityId();
System.out.println("activityId = " + activityId);
String activityName = historicActivityInstance.getActivityName();
System.out.println("activityName = " + activityName);
String processDefinitionId = historicActivityInstance.getProcessDefinitionId();
System.out.println("processDefinitionId = " + processDefinitionId);
String processInstanceId = historicActivityInstance.getProcessInstanceId();
System.out.println("processInstanceId = " + processInstanceId);
}
}
}