1 個人任務
1.1 分配任務負責人
1.1.1 固定分配
- 在進行業務流程建模的時候指定固定的任務負責人。
- 在properties視圖中,添加Assignee項為任務負責人。
由於固定分配方式,任務只管一步一步執行任務,執行到每一個任務將按照BPMN的配置去分配任務負責人。
1.1.2 表達式分配
1.1.2.1 UEL表達式
-
Activiti使用UEL表達式,UEL是JavaEE規范的一部分,URL(Unified Expression Language)即統一表達式語言,Activiti支持兩種UEL表達式:UEL-value和UEL-method。
-
UEL-value定義如下:
- assignee這個變量是Activiti的一個流程變量。
- user這個變量也是Activiti的一個流程變量,user.assignee表示通過調用user的getter方法獲取值。
-
UEL-method定義如下:
- holidayBean是Spring容器中的一個Bean,下圖UEL-method的含義是調用該Bean的一個getHolidayId()方法。
1.1.2.2 使用流程變量分配任務
- 定義任務分配流程變量:
- 設置流程變量:在啟動流程實例的時候設置流程變量
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;
import java.util.HashMap;
import java.util.Map;
/**
* @author <a href="mailto:1900919313@qq.com">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();
//設置流程變量
Map<String, Object> variables = new HashMap<>();
variables.put("assignee0", "張三");
variables.put("assignee1", "李四");
variables.put("assignee2", "王五");
//根據流程定義的key啟動流程實例
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holiday", variables);
//獲取流程實例的相關信息
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);
}
}
1.1.2.3 注意事項
- 由於使用了表達式分配,必須保證在任務執行過程中表達式執行成功,比如某個任務使用了表達式
${order.price > 100 && order.price <250}
,當執行該任務時必須保證order在流程變量中存在,否則Activiti將拋出異常。
1.1.3 監聽器分配
- 任務監聽器是發生對應的任務相關事件時執行自定義的Java邏輯或表達式。
- 任務相關事件包括:
- Event:
- Create:任務創建后觸發。
- Assignment:任務分配后觸發。
- Delete:任務完成后觸發。
- All:所有事件發生都觸發。
- Event:
- 自定義一個任務監聽器類,然后此類必須實現org.activiti.engine.delegate.TaskListener接口:
package com.sunxiaping.task;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;
/**
* @author <a href="mailto:1900919313@qq.com">weiwei.xu</a>
* @version 1.0
* 2020-08-05 15:44
*/
public class SelfTaskListener implements TaskListener {
@Override
public void notify(DelegateTask delegateTask) {
//指定任務的負責人
delegateTask.setAssignee("張三");
}
}
在實際開發中,一般也不使用監聽器分配方式,太麻煩了。
2 流程變量
2.1 什么是流程變量?
- 流程變量在Activiti中是一個非常重要的角色,流程運轉有時需要靠流程變量,業務系統和Activiti結合時少不了流程變量,流程變量就是Activiti在管理工作流時根據管理需要而設置的變量。
- 比如在請假流程流轉時如果請假天數>3天則有總經理審批,否則由人事直接審批,請假天數就可以設置流程變量,在流程流轉時使用。
注意:雖然流程變量中可以存儲業務數據,可以通過Activiti的API查詢流程變量從而實現查詢業務數據,但是不建議這么使用,因為業務數據查詢由業務系統負責,Activiti設置流程變量是為了流程執行需要而創建的。
2.2 流程變量類型
注意:
- 如果將POJO存儲到流程變量中,必須實現序列化接口Serializable,為了防止由於新增字段無法反序列化。
2.3 流程變量的作用域
-
流程變量的作用域范圍可以是一個流程實例(ProcessInstance)、一個任務(Task)或一個執行實例(Execution)。
-
流程變量的作用域范圍的默認值是流程實例,作用域范圍最大,可以稱為global變量。
-
流程變量的作用域范圍如果僅僅針對一個任務或一個執行實例,那么作用域范圍沒有流程實例大,可以稱為local變量。
-
global變量中變量名不允許重復,設置相同名稱的變量,后設置的值會覆蓋前設置的變量值。
-
local變量由於在不同的任務或不同的執行實例中,作用域互不影響,變量名可以相同沒有影響。local變量名也可以和global變量名相同,沒有影響。
2.4 流程變量的使用方法
-
①設置流程變量。
-
②通過UEL表達式使用流程變量。
- 1️⃣可以在assignee處設置UEL表達式,表達值的值就是任務的負責人。例如:${assignee},assignee就是一個流程變量的名稱。
- 2️⃣可以在連線上設置UEL表達式,決定流程的走向。例如:
${holidayNum>=3}
和${holidayNum<3}
中holidayNum就是一個流程變量名稱,UEL表達式的結果類型為boolean類型,如果UEL表達式的值是true,則總經理審批,否則直接人事存檔。
2.5 使用global變量控制流程
2.5.1 需求
- 員工創建請假流程申請單,由部門經理審批,部門經理審批通過后請假3天以下的由人事經理直接審批,3天及3天以上的由總經理審批,總經理審批通過再通過人事經理存檔。
2.5.2 畫流程定義
- 請假大於等於3天的連線條件:
- 請假小於3天的連線條件:
本人在畫BPMN文件的時候將填寫請假申請單的assignee設置為張三,部門經理審批的assignee設置為李四,總經理審批的assignee設置為王五,人事經理存檔設置為趙六。
2.5.3 設置global流程變量
2.5.3.1 准備工作
- 導入相關jar包的Maven坐標:
<properties>
<activiti.version>7.0.0.GA</activiti.version>
</properties>
<dependencies>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>7.0.0.GA</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-model</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-converter</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-json-converter</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-layout</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti.cloud</groupId>
<artifactId>activiti-cloud-services-api</artifactId>
<version>7-201802-EA</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- log start -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.13.3</version>
</dependency>
<!-- log end -->
<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>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.activiti.cloud.dependencies</groupId>
<artifactId>activiti-cloud-dependencies</artifactId>
<version>7.0.0.GA</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
- 日志文件(log4j2.xml)
<?xml version="1.0" encoding="UTF-8"?>
<!--日志級別以及優先級排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status用於設置log4j2自身內部的信息輸出,可以不設置,當設置成trace時,可以看到log4j2內部各種詳細輸出-->
<configuration status="INFO">
<!--先定義所有的appender-->
<appenders>
<!--輸出日志信息到控制台-->
<console name="Console" target="SYSTEM_OUT">
<!--控制日志輸出的格式-->
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</console>
</appenders>
<!--然后定義logger,只有定義了logger並引入的appender,appender才會生效-->
<!--root:用於指定項目的根日志,如果沒有單獨指定Logger,則會使用root作為默認的日志輸出-->
<loggers>
<root level="INFO">
<appender-ref ref="Console"/>
</root>
</loggers>
</configuration>
- Activiti的核心配置文件(activiti-cfg.xml)
<?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.1.146: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>
- 請假實體類(Holiday.java)
package com.sunxiaping.task;
import java.io.Serializable;
import java.util.Date;
/**
* 請假實體類
*
* @author <a href="mailto:1900919313@qq.com">weiwei.xu</a>
* @version 1.0
* 2020-08-06 14:30
*/
public class Holiday implements Serializable {
/**
* 主鍵
*/
private Integer id;
/**
* 申請人名字
*/
private String holidayName;
/**
* 開始時間
*/
private Date beginDate;
/**
* 結束時間
*/
private Date endDate;
/**
* 請假天數
*/
private Float num;
/**
* 請假事由
*/
private String reason;
/**
* 請假類型:病假、婚假、喪假等
*/
private String type;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getHolidayName() {
return holidayName;
}
public void setHolidayName(String holidayName) {
this.holidayName = holidayName;
}
public Date getBeginDate() {
return beginDate;
}
public void setBeginDate(Date beginDate) {
this.beginDate = beginDate;
}
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
public Float getNum() {
return num;
}
public void setNum(Float num) {
this.num = num;
}
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
- 將流程定義和對應的圖片放入到resources目錄下:
2.5.3.2 啟動流程時設置
- 示例:
package com.sunxiaping.test;
import com.sunxiaping.task.Holiday;
import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* global流程變量測試:啟動流程時設置
*
* @author <a href="mailto:1900919313@qq.com">weiwei.xu</a>
* @version 1.0
* 2020-08-06 14:28
*/
public class ActivitiGlobalVariableStartProcessInstanceTest {
ProcessEngine processEngine = null;
@Before
public void before() {
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
processEngine = configuration.buildProcessEngine();
}
@After
public void after() {
if (processEngine != null) {
processEngine.close();
}
}
/**
* 流程定義部署
*/
@Test
public void testDeployment() {
//獲取RepositoryService對象
RepositoryService repositoryService = processEngine.getRepositoryService();
//獲取Deployment對象
Deployment deployment = repositoryService.createDeployment()
.addClasspathResource("diagram/holiday.bpmn")
.addClasspathResource("diagram/holiday.png")
.name("請假申請流程")
.deploy();
String id = deployment.getId();
System.out.println("流程部署的id = " + id);
String name = deployment.getName();
System.out.println("流程部署的名稱 = " + name);
String key = deployment.getKey();
System.out.println("流程部署的key = " + key);
}
/**
* 啟動流程的時候給流程變量賦值
*/
@Test
public void testStartProcessInstance() {
//流程定義的key
String processDefinitionKey = "holiday";
//獲取RuntimeService對象
RuntimeService runtimeService = processEngine.getRuntimeService();
//封裝global流程變量
Holiday holiday = new Holiday();
holiday.setNum(3f);
holiday.setHolidayName("如花");
holiday.setId(1);
holiday.setType("年假");
holiday.setReason("想男友了");
holiday.setBeginDate(new Date());
LocalDateTime endLocalDateTime = LocalDateTime.now().plusDays(3);
Date endDate = Date.from(endLocalDateTime.atZone(ZoneId.systemDefault()).toInstant());
holiday.setEndDate(endDate);
Map<String, Object> variables = new HashMap<>();
variables.put("holiday", holiday);
//根據流程定義的key啟動流程實例
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, variables);
String id = processInstance.getId();
System.out.println("流程實例的id = " + id);
String name = processInstance.getName();
System.out.println("流程實例的名稱 = " + name);
String processDefinitionId = processInstance.getProcessDefinitionId();
System.out.println("流程定義的id = " + processDefinitionId);
}
/**
* 測試張三完成任務
*/
@Test
public void testZhangSanTask() {
String assignee = "張三";
//流程定義的key
String processDefinitionKey = "holiday";
//獲取TaskService對象
TaskService taskService = processEngine.getTaskService();
//獲取張三任務的列表
List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
for (Task task : taskList) {
//任務的id
String id = task.getId();
System.out.println("張三任務的id = " + id);
taskService.complete(id);
}
}
/**
* 測試李四完成任務
*/
@Test
public void testLiSiTask() {
String assignee = "李四";
//流程定義的key
String processDefinitionKey = "holiday";
//獲取TaskService對象
TaskService taskService = processEngine.getTaskService();
//獲取李四任務的列表
List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
for (Task task : taskList) {
//任務的id
String id = task.getId();
System.out.println("李四任務的id = " + id);
taskService.complete(id);
}
}
/**
* 測試王五和趙六的任務,查看到底是王五還是趙六有任務
*/
@Test
public void testWangWuTask() {
String assignee = "王五";
//流程定義的key
String processDefinitionKey = "holiday";
//獲取TaskService對象
TaskService taskService = processEngine.getTaskService();
//獲取王五任務的列表
List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
for (Task task : taskList) {
//任務的id
String id = task.getId();
System.out.println("王五任務的id = " + id);
}
assignee = "趙六";
taskService = processEngine.getTaskService();
//獲取趙六任務的列表
taskList = taskService.createTaskQuery().taskAssignee(assignee).list();
for (Task task : taskList) {
//任務的id
String id = task.getId();
System.out.println("趙六任務的id = " + id);
}
}
}
2.5.3.3 完成任務時設置
- 示例:
package com.sunxiaping.test;
import com.sunxiaping.task.Holiday;
import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* global流程變量測試:完成任務時設置
*
* @author <a href="mailto:1900919313@qq.com">weiwei.xu</a>
* @version 1.0
* 2020-08-06 14:28
*/
public class ActivitiGlobalVariableCompleteTaskTest {
ProcessEngine processEngine = null;
@Before
public void before() {
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
processEngine = configuration.buildProcessEngine();
}
@After
public void after() {
if (processEngine != null) {
processEngine.close();
}
}
/**
* 流程定義部署
*/
@Test
public void testDeployment() {
//獲取RepositoryService對象
RepositoryService repositoryService = processEngine.getRepositoryService();
//獲取Deployment對象
Deployment deployment = repositoryService.createDeployment()
.addClasspathResource("diagram/holiday.bpmn")
.addClasspathResource("diagram/holiday.png")
.name("請假申請流程")
.deploy();
String id = deployment.getId();
System.out.println("流程部署的id = " + id);
String name = deployment.getName();
System.out.println("流程部署的名稱 = " + name);
String key = deployment.getKey();
System.out.println("流程部署的key = " + key);
}
/**
* 啟動流程
*/
@Test
public void testStartProcessInstance() {
//流程定義的key
String processDefinitionKey = "holiday";
//獲取RuntimeService對象
RuntimeService runtimeService = processEngine.getRuntimeService();
//根據流程定義的key啟動流程實例
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey);
String id = processInstance.getId();
System.out.println("流程實例的id = " + id);
String name = processInstance.getName();
System.out.println("流程實例的名稱 = " + name);
String processDefinitionId = processInstance.getProcessDefinitionId();
System.out.println("流程定義的id = " + processDefinitionId);
}
/**
* 測試張三完成任務,張三完成任務的時候給global變量賦值
*/
@Test
public void testZhangSanTask() {
String assignee = "張三";
//流程定義的key
String processDefinitionKey = "holiday";
//獲取TaskService對象
TaskService taskService = processEngine.getTaskService();
//獲取張三任務的列表
List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
for (Task task : taskList) {
//任務的id
String id = task.getId();
System.out.println("張三任務的id = " + id);
//封裝global流程變量
Holiday holiday = new Holiday();
holiday.setNum(3f);
holiday.setHolidayName("如花");
holiday.setId(1);
holiday.setType("年假");
holiday.setReason("想男友了");
holiday.setBeginDate(new Date());
LocalDateTime endLocalDateTime = LocalDateTime.now().plusDays(3);
Date endDate = Date.from(endLocalDateTime.atZone(ZoneId.systemDefault()).toInstant());
holiday.setEndDate(endDate);
Map<String, Object> variables = new HashMap<>();
variables.put("holiday", holiday);
taskService.complete(id, variables);
}
}
/**
* 測試李四完成任務
*/
@Test
public void testLiSiTask() {
String assignee = "李四";
//流程定義的key
String processDefinitionKey = "holiday";
//獲取TaskService對象
TaskService taskService = processEngine.getTaskService();
//獲取李四任務的列表
List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
for (Task task : taskList) {
//任務的id
String id = task.getId();
System.out.println("李四任務的id = " + id);
taskService.complete(id);
}
}
/**
* 測試王五和趙六的任務,查看到底是王五還是趙六有任務
*/
@Test
public void testWangWuTask() {
String assignee = "王五";
//流程定義的key
String processDefinitionKey = "holiday";
//獲取TaskService對象
TaskService taskService = processEngine.getTaskService();
//獲取王五任務的列表
List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
for (Task task : taskList) {
//任務的id
String id = task.getId();
System.out.println("王五任務的id = " + id);
}
assignee = "趙六";
taskService = processEngine.getTaskService();
//獲取趙六任務的列表
taskList = taskService.createTaskQuery().taskAssignee(assignee).list();
for (Task task : taskList) {
//任務的id
String id = task.getId();
System.out.println("趙六任務的id = " + id);
}
}
}
2.5.3.4 通過當前流程實例設置
-
通過流程實例的id設置全局流程變量,該流程實例必須沒有執行完畢。
-
示例:
package com.sunxiaping.test;
import com.sunxiaping.task.Holiday;
import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* global流程變量測試:通過當前流程實例設置
*
* @author <a href="mailto:1900919313@qq.com">weiwei.xu</a>
* @version 1.0
* 2020-08-06 14:28
*/
public class ActivitiGlobalVariableCurrentExecutionIdTest {
ProcessEngine processEngine = null;
@Before
public void before() {
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
processEngine = configuration.buildProcessEngine();
}
@After
public void after() {
if (processEngine != null) {
processEngine.close();
}
}
/**
* 流程定義部署
*/
@Test
public void testDeployment() {
//獲取RepositoryService對象
RepositoryService repositoryService = processEngine.getRepositoryService();
//獲取Deployment對象
Deployment deployment = repositoryService.createDeployment()
.addClasspathResource("diagram/holiday.bpmn")
.addClasspathResource("diagram/holiday.png")
.name("請假申請流程")
.deploy();
String id = deployment.getId();
System.out.println("流程部署的id = " + id);
String name = deployment.getName();
System.out.println("流程部署的名稱 = " + name);
String key = deployment.getKey();
System.out.println("流程部署的key = " + key);
}
/**
* 啟動流程
*/
@Test
public void testStartProcessInstance() {
//流程定義的key
String processDefinitionKey = "holiday";
//獲取RuntimeService對象
RuntimeService runtimeService = processEngine.getRuntimeService();
//根據流程定義的key啟動流程實例
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey);
String id = processInstance.getId();
System.out.println("流程實例的id = " + id);
String name = processInstance.getName();
System.out.println("流程實例的名稱 = " + name);
String processDefinitionId = processInstance.getProcessDefinitionId();
System.out.println("流程定義的id = " + processDefinitionId);
}
/**
* 通過流程實例的id設置流程變量,該流程必須沒有執行完畢
*/
@Test
public void testSetVariable(){
String executionId = "2501";
//封裝global流程變量
Holiday holiday = new Holiday();
holiday.setNum(3f);
holiday.setHolidayName("如花");
holiday.setId(1);
holiday.setType("年假");
holiday.setReason("想男友了");
holiday.setBeginDate(new Date());
LocalDateTime endLocalDateTime = LocalDateTime.now().plusDays(3);
Date endDate = Date.from(endLocalDateTime.atZone(ZoneId.systemDefault()).toInstant());
holiday.setEndDate(endDate);
Map<String, Object> variables = new HashMap<>();
variables.put("holiday", holiday);
//獲取RuntimeService對象
RuntimeService runtimeService = processEngine.getRuntimeService();
//設置流程變量
runtimeService.setVariables(executionId,variables);
}
/**
* 測試張三完成任務
*/
@Test
public void testZhangSanTask() {
String assignee = "張三";
//流程定義的key
String processDefinitionKey = "holiday";
//獲取TaskService對象
TaskService taskService = processEngine.getTaskService();
//獲取張三任務的列表
List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
for (Task task : taskList) {
//任務的id
String id = task.getId();
System.out.println("張三任務的id = " + id);
taskService.complete(id);
}
}
/**
* 測試李四完成任務
*/
@Test
public void testLiSiTask() {
String assignee = "李四";
//流程定義的key
String processDefinitionKey = "holiday";
//獲取TaskService對象
TaskService taskService = processEngine.getTaskService();
//獲取李四任務的列表
List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
for (Task task : taskList) {
//任務的id
String id = task.getId();
System.out.println("李四任務的id = " + id);
taskService.complete(id);
}
}
/**
* 測試王五和趙六的任務,查看到底是王五還是趙六有任務
*/
@Test
public void testWangWuTask() {
String assignee = "王五";
//流程定義的key
String processDefinitionKey = "holiday";
//獲取TaskService對象
TaskService taskService = processEngine.getTaskService();
//獲取王五任務的列表
List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
for (Task task : taskList) {
//任務的id
String id = task.getId();
System.out.println("王五任務的id = " + id);
}
assignee = "趙六";
taskService = processEngine.getTaskService();
//獲取趙六任務的列表
taskList = taskService.createTaskQuery().taskAssignee(assignee).list();
for (Task task : taskList) {
//任務的id
String id = task.getId();
System.out.println("趙六任務的id = " + id);
}
}
}
2.5.3.5 通過當前任務設置
-
該任務必須待辦任務,act_ru_task表中存在。如果該任務已經結束,就會報錯。
-
示例:
package com.sunxiaping.test;
import com.sunxiaping.task.Holiday;
import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* global流程變量測試:通過當前流程實例設置
*
* @author <a href="mailto:1900919313@qq.com">weiwei.xu</a>
* @version 1.0
* 2020-08-06 14:28
*/
public class ActivitiGlobalVariableCurrentTaskIdTest {
ProcessEngine processEngine = null;
@Before
public void before() {
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
processEngine = configuration.buildProcessEngine();
}
@After
public void after() {
if (processEngine != null) {
processEngine.close();
}
}
/**
* 流程定義部署
*/
@Test
public void testDeployment() {
//獲取RepositoryService對象
RepositoryService repositoryService = processEngine.getRepositoryService();
//獲取Deployment對象
Deployment deployment = repositoryService.createDeployment()
.addClasspathResource("diagram/holiday.bpmn")
.addClasspathResource("diagram/holiday.png")
.name("請假申請流程")
.deploy();
String id = deployment.getId();
System.out.println("流程部署的id = " + id);
String name = deployment.getName();
System.out.println("流程部署的名稱 = " + name);
String key = deployment.getKey();
System.out.println("流程部署的key = " + key);
}
/**
* 啟動流程
*/
@Test
public void testStartProcessInstance() {
//流程定義的key
String processDefinitionKey = "holiday";
//獲取RuntimeService對象
RuntimeService runtimeService = processEngine.getRuntimeService();
//根據流程定義的key啟動流程實例
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey);
String id = processInstance.getId();
System.out.println("流程實例的id = " + id);
String name = processInstance.getName();
System.out.println("流程實例的名稱 = " + name);
String processDefinitionId = processInstance.getProcessDefinitionId();
System.out.println("流程定義的id = " + processDefinitionId);
}
/**
* 測試張三完成任務
*/
@Test
public void testZhangSanTask() {
String assignee = "張三";
//流程定義的key
String processDefinitionKey = "holiday";
//獲取TaskService對象
TaskService taskService = processEngine.getTaskService();
//獲取張三任務的列表
List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
for (Task task : taskList) {
//任務的id
String id = task.getId();
//封裝global流程變量
Holiday holiday = new Holiday();
holiday.setNum(3f);
holiday.setHolidayName("如花");
holiday.setId(1);
holiday.setType("年假");
holiday.setReason("想男友了");
holiday.setBeginDate(new Date());
LocalDateTime endLocalDateTime = LocalDateTime.now().plusDays(3);
Date endDate = Date.from(endLocalDateTime.atZone(ZoneId.systemDefault()).toInstant());
holiday.setEndDate(endDate);
Map<String, Object> variables = new HashMap<>();
variables.put("holiday", holiday);
taskService.setVariables(id,variables);
System.out.println("張三任務的id = " + id);
taskService.complete(id);
}
}
/**
* 測試李四完成任務
*/
@Test
public void testLiSiTask() {
String assignee = "李四";
//流程定義的key
String processDefinitionKey = "holiday";
//獲取TaskService對象
TaskService taskService = processEngine.getTaskService();
//獲取李四任務的列表
List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
for (Task task : taskList) {
//任務的id
String id = task.getId();
System.out.println("李四任務的id = " + id);
taskService.complete(id);
}
}
/**
* 測試王五和趙六的任務,查看到底是王五還是趙六有任務
*/
@Test
public void testWangWuTask() {
String assignee = "王五";
//流程定義的key
String processDefinitionKey = "holiday";
//獲取TaskService對象
TaskService taskService = processEngine.getTaskService();
//獲取王五任務的列表
List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
for (Task task : taskList) {
//任務的id
String id = task.getId();
System.out.println("王五任務的id = " + id);
}
assignee = "趙六";
taskService = processEngine.getTaskService();
//獲取趙六任務的列表
taskList = taskService.createTaskQuery().taskAssignee(assignee).list();
for (Task task : taskList) {
//任務的id
String id = task.getId();
System.out.println("趙六任務的id = " + id);
}
}
}
2.5.4 注意事項
- 如果UEL表達式中流程變量名不存在則報錯。
- 如果UEL表達式中流程變量值為null,流程不按UEL表達式去執行,而流程結束。
- 如果UEL表達式都不符合條件,流程結束。
- 如果連接不設置條件,會走flow序號小的那條線。
2.5.5 操作的數據庫表
- 設置流程變量會在當前執行流程變量表(act_ru_variable)插入記錄,同時也會在歷史流程變量表(act_hi_varinst)中也插入記錄。
2.6 設置Local流程變量(實際開發中一般不用)
2.6.1 完成任務前設置
-
在任務完成前設置Local流程變量,當前運行的Local流程變量只能在該任務結束前使用,任務結束該變量無法在當前流程實例使用,可以通過查詢歷史任務查詢。
-
示例:
/**
* 測試張三完成任務
*/
@Test
public void testZhangSanTask() {
String assignee = "張三";
//流程定義的key
String processDefinitionKey = "holiday";
//獲取TaskService對象
TaskService taskService = processEngine.getTaskService();
//獲取張三任務的列表
List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
for (Task task : taskList) {
//任務的id
String id = task.getId();
System.out.println("張三任務的id = " + id);
//封裝global流程變量
Holiday holiday = new Holiday();
holiday.setNum(3f);
holiday.setHolidayName("如花");
holiday.setId(1);
holiday.setType("年假");
holiday.setReason("想男友了");
holiday.setBeginDate(new Date());
LocalDateTime endLocalDateTime = LocalDateTime.now().plusDays(3);
Date endDate = Date.from(endLocalDateTime.atZone(ZoneId.systemDefault()).toInstant());
holiday.setEndDate(endDate);
Map<String, Object> variables = new HashMap<>();
variables.put("holiday", holiday);
taskService.setVariablesLocal(id,variables);
taskService.complete(id);
}
}
2.6.2 通過當前任務設置
- 示例:
/**
* 測試張三完成任務
*/
@Test
public void testZhangSanTask() {
String assignee = "張三";
//流程定義的key
String processDefinitionKey = "holiday";
//獲取TaskService對象
TaskService taskService = processEngine.getTaskService();
//獲取張三任務的列表
List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
for (Task task : taskList) {
//任務的id
String id = task.getId();
//封裝global流程變量
Holiday holiday = new Holiday();
holiday.setNum(3f);
holiday.setHolidayName("如花");
holiday.setId(1);
holiday.setType("年假");
holiday.setReason("想男友了");
holiday.setBeginDate(new Date());
LocalDateTime endLocalDateTime = LocalDateTime.now().plusDays(3);
Date endDate = Date.from(endLocalDateTime.atZone(ZoneId.systemDefault()).toInstant());
holiday.setEndDate(endDate);
Map<String, Object> variables = new HashMap<>();
variables.put("holiday", holiday);
taskService.setVariables(id,variables);
System.out.println("張三任務的id = " + id);
taskService.complete(id);
}
}