流程实例按步骤执行时,需要使用一些数据。在Flowable中,这些数据称作变量(variable),并会存储在数据库中。变量可以用在表达式中(例如在排他网关中用于选择正确的出口路径),也可以在Java服务任务(service task)中用于调用外部服务(例如为服务调用提供输入或结果存储),等等。
流程实例可以持有变量(称作流程变量 process variables);
用户任务以及执行(executions)——流程当前活动节点的指针——也可以持有变量。流程实例可以持有任意数量的变量,每个变量存储为ACT_RU_VARIABLE数据库表的一行。
所有的startProcessInstanceXXX方法都有一个可选参数,用于在流程实例创建及启动时设置变量。例如,在RuntimeService中:
ProcessInstance startProcessInstanceByKey(String processDefinitionKey, Map variables);
也可以在流程执行中加入变量。例如,(RuntimeService):
void setVariable(String executionId, String variableName, Object value);
void setVariableLocal(String executionId, String variableName, Object value);
void setVariables(String executionId, Map variables);
void setVariablesLocal(String executionId, Map variables);
请注意可以为给定执行 设置*局部(local)*变量。(请记住,流程实例由一颗执行的树(tree of executions)组成)
局部变量将只在该执行中可见,对执行树的上层则不可见。这可以用于 数据不应该暴露给流程实例的其他执行,或者变量在流程实例的不同路径中有不同的值(例如使用并行路径时)的情况。
读取变量的方法。请注意TaskService中有类似的方法。这意味着任务与执行一样,可以持有局部变量,其生存期为任务持续的时间。
Map getVariables(String executionId);
Map getVariablesLocal(String executionId);
Map getVariables(String executionId, Collection variableNames);
Map getVariablesLocal(String executionId, Collection variableNames);
Object getVariable(String executionId, String variableName);
T getVariable(String executionId, String variableName, Class variableClass);
下图说明了流程实例、执行实例、任务之间的关系。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ebz7l3Bx-1680843390462)(Flowable学习.assets/image-20230404191928391.png)]
1、全局变量
流程变量的默认作用域是 流程实例。当一个流程变量的作用域是 流程实例 时,可以称为global变量。
global变量变量中变量名不允许重复,设置相同名称的变量,后者设置的值会覆盖掉前者的者。
2、局部变量
任务和执行实例 仅仅是针对一个任务和一个执行实例范围,范围没有流程实力大,称为local变量。
Local 变量由于在不同的任务或不同的执行实例中,作用域互不影响,变量名可以相同,没有影响。local 变量名也可以和 global 变量名相同,没有影响。
3、案例讲解
需求:员工创建出差申请单,由部门经理审核,部门经理申清通过后,3天以下由财务直接审批,3天以上先由总经理审批,总经理审批通过后再由财务审批。
![在这里插入图片描述](https://img-blog.csdnimg.cn/4439228b746c4d76801c7ac443519c84.png)
/**
* 部署流程
*/
@Test
public void TestDeployment() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
Deployment deployment = repositoryService.createDeployment()
.addClasspathResource("出差申请单.bpmn20.xml")
.name("出差申请单流程")
.deploy();
System.out.println("deployment.getId()" + deployment.getId());
System.out.println("deployment.getName()" + deployment.getName());
}
/**
* 启动流程实例
*/
@Test
public void TestDeploymentRun() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
// 流程变量
Map variables = new HashMap();
variables.put("assignee0", "张三");
variables.put("assignee1", "李四");
variables.put("assignee2", "王五");
variables.put("assignee3", "赵会计");
// 启动流程实例
ProcessInstance processInstance = runtimeService.startProcessInstanceById("evection:1:70004", variables);
System.out.println("processInstance.getProcessDefinitionId() = " + processInstance.getProcessDefinitionId());
System.out.println("processInstance.getActivityId() = " + processInstance.getActivityId());
System.out.println("processInstance.getId()" + processInstance.getId());
}
/**
* 删除流程定义
*/
@Test
public void TestDeploymentDelete() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
// 第一个参数是id,如果部署的流程启动了,就不允许删除了
// repositoryService.deleteDeployment("30001");
// 第二个参数是级联删除,如果流程启动了,相关的任务一并会被删除
repositoryService.deleteDeployment("57501", true);
}
/**
* 完成任务,指定流程变量
*/
@Test
public void TestCompleteTask() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
Task task = taskService.createTaskQuery()
.processInstanceId("72501") //根据流程实例编号查找
.taskAssignee("张三")
.singleResult();
// 获取当前流程实例的所有的变量
Map processVariables = task.getProcessVariables();
processVariables.put("num", 2);
taskService.complete(task.getId(), processVariables);
}
/**
* 设置了局部变量
*/
@Test
public void updateVariablesLocal() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
Task task = taskService.createTaskQuery()
.processInstanceId("72501") //根据流程实例编号查找
.taskAssignee("李四")
.singleResult();
// 获取当前流程实例的所有的变量
Map processVariables = task.getProcessVariables();
//null,得不到。可以通过taskService得到全局变量 num 2
System.out.println("测试 processVariables.get(\"num\") = " + processVariables.get("num"));
processVariables.put("num", 6);
// 设置了局部变量,跟执行实例、任务实例绑定了
taskService.setVariablesLocal(task.getId(), processVariables);
}
/**
* 设置全局变量
*/
@Test
public void updateVariables() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
Task task = taskService.createTaskQuery()
.processInstanceId("72501") //根据流程实例编号查找
.taskAssignee("李四")
.singleResult();
Map processVariables = task.getProcessVariables();
//null,得不到。可以通过taskService.getVariable(task.getId(), "num")得到局部变量 num 6
System.out.println("测试 processVariables.get(\"num\") = " + processVariables.get("num"));
processVariables.put("num", 1);
// 设置全局变量
taskService.setVariables(task.getId(), processVariables);//结果把局部变量6 改成了 1
}
/**
* 完成任务,李四
*/
@Test
public void TestCompleteTask2() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
Task task = taskService.createTaskQuery()
.processInstanceId("72501") //根据流程实例编号查找
.taskAssignee("李四")
// .includeProcessVariables().includeTaskLocalVariables()
.singleResult();
Map processVariables = task.getProcessVariables();
// Map taskLocalVariables = task.getTaskLocalVariables();
//null,得不到。可以通过taskService.getVariable(task.getId(), "num")得到局部变量 num 1
System.out.println("测试 processVariables.get(\"num\") = " + processVariables.get("num"));
// 完成任务之后,数据库中发现局部变量 num 1 消失了,而且走到了财务那里,全局变量num并没有使用到
// 在完成任务时用到的是 局部变量num 1
taskService.complete(task.getId());
}
发现全局变量、局部变量的使用,要注意它们的方法,多测试。
在得到task的时候,调用.includeProcessVariables().includeTaskLocalVariables()方法,task身上包含了全局变量、局部变量。
|