1.什么是流程变量
流程变量在 activiti 中是一个非常重要的角色,流程运转有时需要靠流程变量,业务系统和 activiti 结合时少不了流程变量,流程变量就是 activiti 在管理工作流时根据管理需要而设置的变量。
比如在请假流程流转时如果请假天数大于 3 天则由总经理审核,否则由人事直接审核,请假天数就可以设置为流程变量,在流程流转时使用。
注意:
如果将 pojo 存储到流程变量中,必须实现序列化接口 serializable,为了防止由于新增字段无法反序列化,需要生成 serialVersionUID
2.流程变量作用域
流程变量的作用域默认是一个流程实例(processInstance),也可以是一个任务(task)或一个执行实例(execution),这三个作用域流程实例的范围最大,可以称为 global 变量,任务和执行实例仅仅是针对一个任务和一个执行实例范围,范围没有流程实例大,称为 local 变量。
-
global 变量中变量名不允许重复,设置相同名称的变量,后设置的值会覆盖前设置的变量值。
-
Local 变量由于在不同的任务或不同的执行实例中,作用域互不影响,变量名可以相同没有影响。
-
Local 变量名也可以和 global 变量名相同,没有影响。
3.流程变量使用方法
第一步:设置流程变量
第二步:通过UEL表达式使用流程变量
(1)可以在assginee处设置UEL表达式,表达式的值为任务的负责人,比如${assignee}
(2)可以在连线上设置UEL表达式,决定流程走向,比如${num>3}
4.使用Global变量控制流程
(1)需求
员工创建请假申请单,由部门经理审核,部门经理审核通过后请假 3 天及以下由人事经理直接审核,3 天以上先由总经理审核,总经理审核通过再由人事经理存档。
(2)流程定义
流程审批的人为方便测试设置为固定值:
填写请假申请单:zhangsan
部门经理审批:lisi
总经理审批:wangwu
人事经理存档:zhaoliu
根据请假天数走不同的分支:
(3)启动流程时设置
在启动流程时设置流程变量,变量的作用域是整个流程实例。
通过 map<key,value>设置流程变量,map 中可以设置多个变量,这个 key 就是流程变量的名字。
// 启动流程时设置流程变量
@Test
public void startProcessInstance() {
// 流程定义key
String processDefinitionKey = "";
Holiday holiday = new Holiday();
holiday.setNum(3f);
// 定义流程变量
Map<String, Object> variables = new HashMap<>();
//变量名是num,变量值是holiday.getNum(),变量名也可以是一个对象
variables.put("num", holiday.getNum());
//1.创建ProcessEngineer对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取runtimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
ProcessInstance processInstance = runtimeService
.startProcessInstanceByKey(processDefinitionKey, variables);
System.out.println(" 流 程 实 例 id:" + processInstance.getProcessInstanceId());
}
(4)创建请假实体类对象
/**
* 请假实体类:
* 注意POJO类型,一定要实现Serializable接口,否则在存储这个pojo时就会报异常
*/
@Data
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;//请假类型
}
(4)流程定义部署
//新的请假流程定义的部署
public static void main(String[] args) {
//1.得到ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到RepositoryService对象
RepositoryService repositoryService = processEngine.getRepositoryService();
//3.部署
Deployment deploy = repositoryService.createDeployment()
.addClasspathResource("diagram/holiday4.bpmn")
.addClasspathResource("diagram/holiday4.png")
.name("请假流程-流程变量")
.deploy();
System.out.println(deploy.getId());
System.out.println(deploy.getName());
}
(5)启动流程实例
//启动流程实例,同时还要设置流程变量的值
// act_ge_bytearray
// act_ru_variable
public static void main(String[] args) {
//1.得到ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到RuntimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
//3.流程定义的key问题
String key = "holiday4";
Map<String ,Object> map = new HashMap<>();
Holiday holiday = new Holiday();
holiday.setNum(5F);
map.put("holiday",holiday);
//4.启动流程实例,并且设置流程变量的值
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key, map);
//5.输出实例信息
System.out.println(processInstance.getName());
System.out.println(processInstance.getProcessDefinitionId());
}
(6)执行流程
依次执行zhangsan,lisi,wangwu,zhaoliu的任务
public static void main(String[] args) {
//完成任务 zhangsan -----lisi----判断流程变量的请假天数,1天----分支:人事经理存档(zhaoliu)
//1.得到ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到TaskService
TaskService taskService = processEngine.getTaskService();
//3.查询当前用户是否有任务
String key = "holiday4";
Task task = taskService.createTaskQuery().processDefinitionKey(key)
.taskAssignee("zhangsan").singleResult();
//4.判断task!=null,说明当前用户有任务
if(task!=null){
taskService.complete(task.getId());
System.out.println("任务执行完毕");
}
}
通过创建流程实例时设置的请假天数num变量,可以发现当num>3的时候,在通过部门经理审批后,会先走总经理审批。当num=3的时候,在通过部门经理审批后,就可以直接到达人事经理存档环节。
(7)global变量的其它设置方法
global除了在启动流程时设置,还可以在以下步骤中设置
-
任务办理时设置
在完成任务时设置流程变量,该流程变量只有在该任务完成后其它结点才可使用该变量,它的作用域是整个流程实例,如果设置的流程变量的 key 在流程实例中已存在相同的名字则后设置的变量替换前边设置的变量。
public static void main(String[] args) {
//1.得到ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到TaskService
TaskService taskService = processEngine.getTaskService();
//3.查询当前用户是否有任务
String key = "holiday4";
Task task = taskService.createTaskQuery().processDefinitionKey(key)
.taskAssignee("zhangsan").singleResult();
//初始化一些参数
Map<String ,Object> map = new HashMap<>();
Holiday holiday = new Holiday();
holiday.setNum(5F);
map.put("holiday",holiday);
//4.判断task!=null,说明当前用户有任务
if(task!=null){
taskService.complete(task.getId(),map);//完成任务时,设置流程变量的值
System.out.println("任务执行完毕");
}
}
-
通过当前流程实例设置
通过流程实例 id 设置全局变量,该流程实例必须未执行完成
public static void main(String[] args) {
//1.得到ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到RuntimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
//3.流程定义的key问题 myProcess_1
//Map<String ,Object> map = new HashMap<>();
Holiday holiday = new Holiday();
holiday.setNum(5F);
// map.put("holiday",holiday);
//4.通过实例id,来设置流程变量
//第一个参数:流程实例的id
//第二个参数:流程变量名
//第三个变量:流程变量名,所对应的值
runtimeService.setVariable("2501","holiday",holiday);
}
-
通过当前任务设置
public static void main(String[] args) {
//当前待办任务id String taskId="1404";
//1.得到ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
Holiday holiday = new Holiday();
holiday.setNum(3f);
//通过任务设置流程变量
taskService.setVariable("1404", "holiday", holiday);
//一次设置多个值
//taskService.setVariables(taskId, variables)
}
5.设置local流程变量
(1)任务办理时设置
任务办理时设置 local 流程变量,当前运行的流程实例只能在该任务结束前使用,任务结束该变量无法在当前流程实例使用,可以通过查询历史任务查询。
// 办理任务时设置local流程变量
@Test
public void completTask() { //任务id
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
String taskId = "1404";
TaskService taskService = processEngine.getTaskService();
// 定义流程变量
Map<String, Object> variables = new HashMap<String, Object>();
Holiday holiday = new Holiday();
holiday.setNum(3f);
// 定义流程变量
variables.put("holiday", holiday);
// 设置local变量,作用域为该任务
// taskService.setVariablesLocal(tasked, variables);
taskService.complete(taskId);
}
(2)通过当前任务设置
@Test
public void setLocalVariableByTaskId(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//当前待办任务id
String taskId="1404";
TaskService taskService = processEngine.getTaskService(); Holiday holiday = new Holiday ();
holiday.setNum(3f);
//通过任务设置流程变量
taskService.setVariableLocal(taskId, "holiday", holiday);
//一次设置多个值
//taskService.setVariablesLocal(taskId, variables)
}