Activiti提供了流程运行时对流程进行控制的API,可以使用RuntimeService提供的方法对流程进行控制,与先前博客中提到的一样,RuntimeService是Activiti提供的业务组件之一。前几篇博客中介绍的TaskService主要用于任务管理,包括任务操作,任务数据管理等;IdentityService主要用于管理流程的身份数据;RepositoryService主要用于管理流程部署的数据;而本篇博客要学习的RuntimeService主要用于管理流程在运行时产生的数据以及提供对流程进行操作的API。其中流程运行时产生的数据包括流程参数、事件、流程实例以及执行流等。
什么是流程实例与执行流
在Activiti中,启动了一个流程后,就会创建一个流程实例(ProcessInstance),每个流程实例至少会有一个执行流(Execution);如果流程中出现了分支,那么执行流的概念就出现了。所以一个流程实例就是一个执行流,这就是区别所在。
RuntimeService中的查询操作
执行流查询
RuntimeService中有createExecutionQuery方法可以得到一个ExecutionQuery对象,该对象就可以根据执行流的相关数据查询执行流。直接看个例子吧!从实战中学习。
<span style="font-family:Comic Sans MS;font-size:18px;">public class ExecutionQuery { public static void main(String[] args) { // 创建流程引擎 ProcessEngine engine = ProcessEngines.getDefaultProcessEngine(); // 得到流程存储服务实例 RepositoryService repositoryService = engine.getRepositoryService(); // 得到运行时服务组件 RuntimeService runtimeService = engine.getRuntimeService(); // 部署流程描述文件 repositoryService.createDeployment() .addClasspathResource("bpmn/ExecutionQuery.bpmn").deploy(); //设置参数 Map<String, Object> vars1 = new HashMap<String, Object>(); vars1.put("days", 5); Map<String, Object> vars2 = new HashMap<String, Object>(); vars2.put("days", 6); Map<String, Object> vars3 = new HashMap<String, Object>(); vars3.put("days", 7); vars3.put("name", "crazyit"); // 开始流流程 ProcessInstance pi1 = runtimeService.startProcessInstanceByKey("testProcess", "businessKey1", vars1); ProcessInstance pi2 = runtimeService.startProcessInstanceByKey("testProcess", "businessKey2", vars2); ProcessInstance pi3 = runtimeService.startProcessInstanceByKey("testProcess", "businessKey3", vars3); // 使用执行流查询方法 List<Execution> exes = runtimeService.createExecutionQuery() .processDefinitionKey("testProcess").list(); System.out.println("使用processDefinitionKey方法查询执行流:" + exes.size()); exes = runtimeService.createExecutionQuery() .processInstanceBusinessKey("businessKey1").list(); System.out.println("使用processInstanceBusinessKey方法查询执行流:" + exes.size()); exes = runtimeService.createExecutionQuery() .messageEventSubscriptionName("messageName").list(); System.out.println("使用messageEventSubscriptionName方法查询执行流:" + exes.size()); // 根据节点id属性查询当前的执行流 Execution exe = runtimeService.createExecutionQuery() .activityId("messageintermediatecatchevent1") .processInstanceId(pi1.getId()).singleResult(); System.out.println("使用activityId和processInstanceId方法查询执行流,得到执行ID:" + exe.getId()); //让流程往下执行 runtimeService.messageEventReceived("messageName", exe.getId()); exes = runtimeService.createExecutionQuery().signalEventSubscriptionName("signalName").list(); System.out.println("使用signalEventSubscriptionName方法查询执行流:" + exes.size()); // 根据参数查询执行流 exes = runtimeService.createExecutionQuery().variableValueEquals("name", "crazyit").list(); System.out.println("使用variableValueEquals方法查询执行流:" + exes.size()); exes = runtimeService.createExecutionQuery().variableValueGreaterThan("days", 5).list(); System.out.println("使用variableValueGreaterThan方法查询执行流:" + exes.size()); exes = runtimeService.createExecutionQuery().variableValueGreaterThanOrEqual("days", 5).list(); System.out.println("使用variableValueGreaterThanOrEqual方法查询执行流:" + exes.size()); exes = runtimeService.createExecutionQuery().variableValueLessThan("days", 6).list(); System.out.println("使用variableValueLessThan方法查询执行流:" + exes.size()); exes = runtimeService.createExecutionQuery().variableValueLessThanOrEqual("days", 6).list(); System.out.println("使用variableValueLessThanOrEqual方法查询执行流:" + exes.size()); exes = runtimeService.createExecutionQuery().variableValueLike("name", "%crazy%").list(); System.out.println("使用variableValueLike方法查询执行流:" + exes.size()); exes = runtimeService.createExecutionQuery().variableValueNotEquals("days", 8).list(); System.out.println("使用variableValueNotEquals方法查询执行流:" + exes.size()); } }</span>
流程实例查询
与上述类似,也可以通过RuntimeService的createProcessInstanceQuery方法获取ProcessInstanceQuery实例,在该实例中也为我们提供了有关流程实例的查询方法
<span style="font-family:Comic Sans MS;font-size:18px;">public class ProcessInstanceQuery { public static void main(String[] args) { // 创建流程引擎 ProcessEngine engine = ProcessEngines.getDefaultProcessEngine(); // 得到流程存储服务实例 RepositoryService repositoryService = engine.getRepositoryService(); // 得到运行时服务组件 RuntimeService runtimeService = engine.getRuntimeService(); // 部署流程描述文件 repositoryService.createDeployment() .addClasspathResource("bpmn/ProcessInstanceQuery.bpmn") .deploy(); ProcessInstance pi1 = runtimeService.startProcessInstanceByKey( "testProcess", "key1"); ProcessInstance pi2 = runtimeService.startProcessInstanceByKey( "testProcess", "key2"); ProcessInstance pi3 = runtimeService.startProcessInstanceByKey( "testProcess", "key3"); // 将流程置为中断状态 runtimeService.suspendProcessInstanceById(pi1.getId()); // 查询流程实例 List<ProcessInstance> pis = runtimeService.createProcessInstanceQuery() .processDefinitionKey("testProcess").list(); System.out.println("使用processDefinitionKey方法查询流程实例:" + pis.size()); pis = runtimeService.createProcessInstanceQuery().active().list(); System.out.println("使用active方法查询流程实例:" + pis.size()); pis = runtimeService.createProcessInstanceQuery() .processInstanceBusinessKey("key2").list(); System.out .println("使用processInstanceBusinessKey方法查询流程实例:" + pis.size()); // 根据多个流程实例ID查询 Set<String> ids = new HashSet<String>(); ids.add(pi1.getId()); ids.add(pi2.getId()); pis = runtimeService.createProcessInstanceQuery() .processInstanceIds(ids).list(); System.out.println("使用processInstanceIds方法查询流程实例:" + pis.size()); } } </span>
启动流程
RuntimeServcie中也为我们提供了很多启动流程的方法,方法统一命名为startProcessInstanceByXXX,其中XXX有流程定义ID、流程定义的key(流程描述文件中的process的id属性)和流程中定义的额message。
startProcessInstanceById方法
<span style="font-family:Comic Sans MS;font-size:18px;">public class StartById { /** * @param args */ public static void main(String[] args) { // 创建流程引擎 ProcessEngine engine = ProcessEngines.getDefaultProcessEngine(); // 得到流程存储服务实例 RepositoryService repositoryService = engine.getRepositoryService(); RuntimeService runtimeService = engine.getRuntimeService(); // 部署流程描述文件 Deployment dep = repositoryService.createDeployment() .addClasspathResource("bpmn/startById.bpmn20.xml").deploy(); // 查找流程定义 ProcessDefinition pd = repositoryService.createProcessDefinitionQuery() .deploymentId(dep.getId()).singleResult(); //设置流程参数 Map<String, Object> vars = new HashMap<String, Object>(); vars.put("days", 5); //启动流程 runtimeService.startProcessInstanceById(pd.getId()); runtimeService.startProcessInstanceById(pd.getId(), vars); runtimeService.startProcessInstanceById(pd.getId(), "vacationRequest1"); runtimeService.startProcessInstanceById(pd.getId(), "vacationRequest2", vars); // 查询流程实例,结果为4 long count = runtimeService.createProcessInstanceQuery().count(); System.out.println("流程实例数量:" + count); } } </span>
startProcessInstanceByKey方法
<span style="font-family:Comic Sans MS;font-size:18px;">public class StartByKey { /** * @param args */ public static void main(String[] args) { // 创建流程引擎 ProcessEngine engine = ProcessEngines.getDefaultProcessEngine(); // 得到流程存储服务实例 RepositoryService repositoryService = engine.getRepositoryService(); RuntimeService runtimeService = engine.getRuntimeService(); // 部署流程描述文件 repositoryService.createDeployment() .addClasspathResource("bpmn/startByKey.bpmn20.xml").deploy(); //初始化流程参数 Map<String, Object> vars = new HashMap<String, Object>(); vars.put("days", 4); //启动流程 runtimeService.startProcessInstanceByKey("vacationRequest"); runtimeService.startProcessInstanceByKey("vacationRequest", vars); runtimeService.startProcessInstanceByKey("vacationRequest", "testKey"); runtimeService.startProcessInstanceByKey("vacationRequest", "testKey2", vars); // 查询流程实例,结果为4 long count = runtimeService.createProcessInstanceQuery().count(); System.out.println("流程实例数量:" + count); } } </span>
startProcessInstanceByMessage方法
<span style="font-family:Comic Sans MS;font-size:18px;">public class StartByMessage { /** * @param args */ public static void main(String[] args) { // 创建流程引擎 ProcessEngine engine = ProcessEngines.getDefaultProcessEngine(); // 得到流程存储服务实例 RepositoryService repositoryService = engine.getRepositoryService(); RuntimeService runtimeService = engine.getRuntimeService(); // 部署流程描述文件 repositoryService.createDeployment() .addClasspathResource("bpmn/startByMessage.bpmn20.xml").deploy(); //初始化流程参数 Map<String, Object> vars = new HashMap<String, Object>(); vars.put("days", 4); //启动流程 runtimeService.startProcessInstanceByMessage("startMsg"); runtimeService.startProcessInstanceByMessage("startMsg", vars); runtimeService.startProcessInstanceByMessage("startMsg", "testKey"); runtimeService.startProcessInstanceByMessage("startMsg", "testKey2", vars); // 查询流程实例,结果为4 long count = runtimeService.createProcessInstanceQuery().count(); System.out.println("流程实例数量:" + count); } } </span>
RuntimeService组件跟其他组件类似,也可以在流程运行的过程中来设置参数,方法与其他组件都类似,并且参数也有作用域的问题。在此就给个demo看一下吧
<span style="font-family:Comic Sans MS;font-size:18px;">public class SetVariableLocal { public static void main(String[] args) { // 创建流程引擎 ProcessEngine engine = ProcessEngines.getDefaultProcessEngine(); // 得到流程存储服务实例 RepositoryService repositoryService = engine.getRepositoryService(); // 得到运行时服务组件 RuntimeService runtimeService = engine.getRuntimeService(); // 得到任务 TaskService taskService = engine.getTaskService(); // 部署流程描述文件 repositoryService.createDeployment() .addClasspathResource("bpmn/localVariable.bpmn20.xml").deploy(); //启动流程 ProcessInstance pi = runtimeService.startProcessInstanceByKey("vacationRequest"); //查询全部的任务,得到相应的执行流,设置不同的参数 List<Task> tasks = taskService.createTaskQuery().processInstanceId(pi.getId()).list(); for (Task task : tasks) { Execution exe = runtimeService.createExecutionQuery() .executionId(task.getExecutionId()).singleResult(); if ("Manager Audit".equals(task.getName())) { //经理审核节点,设置Local参数 runtimeService.setVariableLocal(exe.getId(), "managerVar", "manager var"); } else { //HR审核节点,设置全局参数 runtimeService.setVariable(exe.getId(), "hrVar", "hr var"); } } //两个执行流时输出参数 for (Task task : tasks) { Execution exe = runtimeService.createExecutionQuery() .executionId(task.getExecutionId()).singleResult(); if ("Manager Audit".equals(task.getName())) { System.out.println("使用getVariableLocal方法获取经理参数:" + runtimeService.getVariableLocal(exe.getId(), "managerVar")); System.out.println("使用getVariable方法获取经理参数:" + runtimeService.getVariableLocal(exe.getId(), "managerVar")); } else { System.out.println("使用getVariableLocal方法获取HR参数:" + runtimeService.getVariableLocal(exe.getId(), "hrVar")); System.out.println("使用getVariable方法获取HR参数:" + runtimeService.getVariable(exe.getId(), "hrVar")); } } //完成任务 for (Task task : tasks) { taskService.complete(task.getId()); } System.out.println("======== 完成流程分支后 ========"); //重新查找流程任务 tasks = taskService.createTaskQuery().processInstanceId(pi.getId()).list(); for (Task task : tasks) { System.out.println("当前流程节点:" + task.getName()); Execution exe = runtimeService.createExecutionQuery() .executionId(task.getExecutionId()).singleResult(); System.out.println("经理参数:" + runtimeService.getVariable(exe.getId(), "managerVar")); System.out.println("HR参数:" + runtimeService.getVariable(exe.getId(), "hrVar")); } } } </span>