一.简介
为什么需要流程变量。
举个例子,假设有如下一个流程,截图如下:
这是一个请假流程,那么谁请假、请几天、起始时间、请假理由等等,这些都需要说明,不然领导审批的依据是啥?那么如何传递这些数据,我们就需要流程变量。
二.流程变量的分类
目前流程变量可以分为三种类型:
- 全局流程变量:在整个流程执行期间,这个流程变量都是有效的。
- 本地流程变量:这个只针对流程中某一个具体的 Task(任务)有效,这个任务执行完毕后,这个流程变量就失效了。
- 临时流程变量:顾名思义就是临时的,这个不会存入到数据库中。
在接下来学习这些流程变量的用法。
三.本地流程变量
上一篇文章说的全局流程变量是和某一个具体的流程绑定的,而本地流程变量则不同,本地流程变量和某一个 Task 绑定。
1.通过 Task 设置
假设启动流程之后,通过 Task 来设置一个本地流程变量,代码如下:
@Test
void test03() {
Task task = taskService.createTaskQuery().singleResult();
taskService.setVariableLocal(task.getId(), "days", 10);
Map<String, Object> variables = new HashMap<>();
variables.put("reason", "休息一下");
variables.put("startTime", new Date());
taskService.setVariables(task.getId(),variables);
}
上面这段代码中,设置了一个本地变量,两个全局变量,设置完成后,去 ACT_RU_VARIABLE 表中来查看一下具体的效果,截图如下:
可以看到,由于 days 是本地变量,所以它的 TASK_ID_ 有值,这个好理解,说明 days 这个变量和这个具体的 Task 是有关的。
此时如果完成这个 Task,代码如下:
@Test
void test06() {
Task task = taskService.createTaskQuery().singleResult();
taskService.complete(task.getId());
}
完成之后,再来查看 ACT_RU_VARIABLE 表,截图如下:
可以看到本地变量 days 已经没有了。因为上一个 Task 都已经执行完毕了,这个时候如果还是按照上一篇第三小节介绍的方式去查询变量,就查不到 days 了。此时如果需要查询到曾经的 days 变量,得去历史表中查询了,代码如下:
@Test
void test07() {
ProcessInstance pi = runtimeService.createProcessInstanceQuery().singleResult();
List<HistoricVariableInstance> list = historyService.createHistoricVariableInstanceQuery().processInstanceId(pi.getId()).list();
for (HistoricVariableInstance hvi : list) {
logger.info("name:{},type:{},value:{}", hvi.getVariableName(), hvi.getVariableTypeName(), hvi.getValue());
}
}
这是流程本地变量的特点,当然相关的方法还有好几个,代码如下:
org.flowable.engine.TaskService#complete(java.lang.String, java.util.Map<java.lang.String,java.lang.Object>, boolean):在完成一个 Task 的时候,如果传递了变量,则可以通过第三个参数来控制这个变量是全局的还是本地的,true 表示这个变量是本地的。
org.flowable.engine.RuntimeService#setVariableLocal:为某一个执行实例设置本地变量。
org.flowable.engine.RuntimeService#setVariablesLocal:同上,批量设置。
四.临时流程变量
临时流程变量是不存数据库的,一般来说可以在启动流程或者完成任务的时候使用,代码如下:
@Test
void test21() {
Map<String, Object> variables = new HashMap<>();
variables.put("reason", "休息一下");
variables.put("startTime", new Date());
ProcessInstance pi = runtimeService
.createProcessInstanceBuilder()
.transientVariable("days", 10)
.transientVariables(variables)
.processDefinitionKey("demo01")
.start();
logger.info("id:{},activityId:{}", pi.getId(), pi.getActivityId());
}
上面这段代码涉及到的流程变量就是临时流程变量,它是不会存入到数据库中的。
也可以在完成一个任务的时候设置临时变量,代码如下:
@Test
void test22() {
Task task = taskService.createTaskQuery().singleResult();
Map<String, Object> transientVariables = new HashMap<>();
transientVariables.put("days", 10);
taskService.complete(task.getId(), null, transientVariables);
}
这个临时变量也是不会存入到数据库中的。