Activiti7进阶之个人任务和流程变量
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);
}
}