流程变量可以用将数据添加到流程的运行时状态中,或者更具体地说,变量作用域中。改变实体的各种API可以用来更新这些附加的变量。一般来说,一个变量由一个名称和一个值组成。名称用于在整个流程中识别变量。例如,如果一个活动(activity)设置了一个名为 var 的变量,那么后续活动中可以通过使用这个名称来访问它。变量的值是一个 Java 对象。
流程实例运行时的变量,存入act_ru_variable表中。在流程实例运行结束时,此实例的变量在表中删除。在流程实例创建及启动时,可设置流程变量。所有的startProcessInstanceXXX
方法都有一个可选参数用于设置变量。例如,RuntimeService
中
ProcessInstance startProcessInstanceById(String processDefinitionId, Map<String, Object> variables);
也可以在流程执行中加入变量。例如,(RuntimeService):
void setVariable(String executionId, String variableName, Object value);
void setVariableLocal(String executionId, String variableName, Object value);
void setVariables(String executionId, Map<String, ? extends Object> variables);
void setVariablesLocal(String executionId, Map<String, ? extends Object> variables);
读取变量方法:
Map<String, Object> getVariables(String executionId);
Map<String, Object> getVariablesLocal(String executionId);
Map<String, Object> getVariables(String executionId, Collection<String> variableNames);
Map<String, Object> getVariablesLocal(String executionId, Collection<String> variableNames);
Object getVariable(String executionId, String variableName);
<T> T getVariable(String executionId, String variableName, Class<T> variableClass);
注意:由于流程实例结束时,对应在运行时表的数据跟着被删除。所以查询一个已经完结流程实例的变量,只能在历史变量表中查找。
当然运行时变量我们也可以根据对应的作用域把他分为全局变量
和局部变量
.
流程变量的默认作用域是流程实例。当一个流程变量的作用域为流程实例时,可以称为 global 变量
注意:如: Global变量:userId(变量名)、zhangsan(变量值)
global 变量中变量名不允许重复,设置相同名称的变量,后设置的值会覆盖前设置的变量值。
案例:
定义监听器
public class MySecondListener implements TaskListener {
@Override
public void notify(DelegateTask delegateTask) {
// 获取所有的流程变量
Map<String, Object> variables = delegateTask.getVariables();
Set<String> keys = variables.keySet();
for (String key : keys) {
Object obj = variables.get(key);
System.out.println(key + " = " + obj);
if(obj instanceof String){
// 修改 流程变量的信息
// variables.put(key,obj + ":boge3306"); 直接修改Map中的数据 达不到修改流程变量的效果
delegateTask.setVariable(key + ":boge3306");
}
}
}
}
然后完成流程的部署操作
@Test
public void test1(){
// 1.获取ProcessEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2.完成流程的部署操作 需要通过RepositoryService来完成
RepositoryService repositoryService = processEngine.getRepositoryService();
// 3.完成部署操作
Deployment deploy = repositoryService.createDeployment()
.addClasspathResource("flow/holiday1.bpmn20.xml")
.name("请假流程-流程变量")
.deploy(); // 是一个流程部署的行为 可以部署多个流程定义的
System.out.println(deploy.getId());
System.out.println(deploy.getName());
}
然后启动流程实例。注意在启动流程实例时我们需要指定相关的流程变量
/**
* 发起一个流程
*/
@Test
public void test3(){
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
// 发起流程 需要通过 runtimeService来实现
RuntimeService runtimeService = engine.getRuntimeService();
// 定义流程变量信息
Map<String,Object> map = new HashMap<>();
map.put("assignee1","张三");
map.put("assignee2","李四");
map.put("ass1","变量1");
map.put("ass2",299);
map.put("ass3","湖南长沙");
map.put("ass4","波哥666");
// 通过流程定义ID来启动流程 返回的是流程实例对象
ProcessInstance processInstance = runtimeService
.startProcessInstanceById("holiday1:1:42503",map);
System.out.println("processInstance.getId() = " + processInstance.getId());
System.out.println("processInstance.getDeploymentId() = " + processInstance.getDeploymentId());
System.out.println("processInstance.getDescription() = " + processInstance.getDescription());
}
启动流程和触发对应的监听器,同时会在act_ru_variable
中记录当前的变量信息
当然我们也可以通过RunTimeService
来查询当前对应的流程实例的流程变量信息
/**
* 查询当前的流程变量信息
*/
@Test
public void testVal(){
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = engine.getRuntimeService();
// 获取流程变量信息 获取某个流程实例的变量信息
Map<String, VariableInstance> variableInstances =
runtimeService.getVariableInstances("50008");
Set<String> keys = variableInstances.keySet();
for (String key : keys) {
System.out.println(key+"="+variableInstances.get(key));
}
}
任务和执行实例仅仅是针对一个任务和一个执行实例范围,范围没有流程实例大, 称为 local 变量。
Local 变量由于在不同的任务或不同的执行实例中,作用域互不影响,变量名可以相同没有影响。Local 变量名也可以和 global 变量名相同,没有影响。
我们通过RuntimeService 设置的Local变量绑定的是 executionId。在该流程中有效
@Test
public void test4(){
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
// 待办查询 执行中的任务处理通过 TaskService来实现
TaskService taskService = engine.getTaskService();
RuntimeService runtimeService = engine.getRuntimeService();
runtimeService.setVariableLocal("60004","orderId","100001");
runtimeService.setVariableLocal("60004","price",6666);
}
我们还可以通过TaskService来绑定本地流程变量。需要指定对应的taskId
@Test
public void test41(){
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
// 待办查询 执行中的任务处理通过 TaskService来实现
TaskService taskService = engine.getTaskService();
taskService.setVariableLocal("60007","wechat","boge3306");
}
然后通过测试演示我们可以看到通过TaskService绑定的Local变量的作用域只是在当前的Task有效。而通过RuntimeService绑定的Local变量作用的访问是executionId。
需要注意:executionId和processInstanceId的区别
历史变量,存入act_hi_varinst
表中。在流程启动时,流程变量会同时存入历史变量表中;在流程结束时,历史表中的变量仍然存在。可理解为“永久代”的流程变量。
获取已完成的、id为’XXX’的流程实例中,所有的HistoricVariableInstances
(历史变量实例),并以变量名排序。
historyService.createHistoricVariableInstanceQuery()
.processInstanceId("XXX")
.orderByVariableName.desc()
.list();