RuntimeService
1. RuntimeService为流程运行控制服务,提供的功能:
-
启动流程及对流程数据的控制
-
流程实例(ProcessInstance)与执行流(Execution)查询
-
触发流程操作、接受消息和信号
2. RuntimeService启动流程及变量管理
-
启动流程的常用方式(id, key, message)
-
启动流程可选参数(businessKey, variables, tenantId)
-
变量(variables)的设置和获取
下面介绍RuntimeService的具体运用。
使用RuntimeService启动流程
key方式启动流程
public class RuntimeServiceTest {
private static final Logger LOGGER = LoggerFactory.getLogger(RuntimeServiceTest.class);
@Rule
public ActivitiRule activitiRule = new ActivitiRule();
@Test//key方式启动流程
//启动流程前先部署流程
@org.activiti.engine.test.Deployment(resources = {"my-process.bpmn20.xml"})
public void testStartProcess(){
RuntimeService runtimeService = activitiRule.getRuntimeService();
Map<String, Object> variables = Maps.newHashMap();
variables.put("key1", "value1");
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process", variables);
LOGGER.info("processInstance = {}",processInstance);
}
}
Id方式启动流程,需要先使用repositoryService获取到流程定义对象,然后再获取到流程id
@Test//Id方式启动流程,需要先使用repositoryService获取到流程定义对象,然后再获取到流程id
@org.activiti.engine.test.Deployment(resources = {"my-process.bpmn20.xml"})
public void testStartProcessById(){
RuntimeService runtimeService = activitiRule.getRuntimeService();
ProcessDefinition processDefinition = activitiRule.getRepositoryService().createProcessDefinitionQuery().singleResult();
Map<String, Object> variables = Maps.newHashMap();
variables.put("key1", "value1");
ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId(), variables);
LOGGER.info("processInstance = {}",processInstance);
}
ProcessInstanceBuilder方式启动流程
@Test//以ProcessInstanceBuilder方式启动流程
@org.activiti.engine.test.Deployment(resources = {"my-process.bpmn20.xml"})
public void testProcessInstanceBuilder(){
RuntimeService runtimeService = activitiRule.getRuntimeService();
Map<String, Object> variables = Maps.newHashMap();
variables.put("key1", "value1");
ProcessInstanceBuilder processInstanceBuilder = runtimeService.createProcessInstanceBuilder();
ProcessInstance processInstance = processInstanceBuilder.businessKey("businessKey001").processDefinitionKey("my-process").variables(variables).start();
LOGGER.info("processInstance = {}",processInstance);
}
修改与获取流程实例中的变量
@Test//修改与获取流程实例中的变量
//启动流程前先部署流程
@org.activiti.engine.test.Deployment(resources = {"my-process.bpmn20.xml"})
public void testVariables(){
RuntimeService runtimeService = activitiRule.getRuntimeService();
Map<String, Object> variables = Maps.newHashMap();
variables.put("key1", "value1");
variables.put("key2", "value2");
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process", variables);
LOGGER.info("processInstance = {}",processInstance);
//使用runtimeService修改变量
runtimeService.setVariable(processInstance.getId(), "key2", "value2_1" );
runtimeService.setVariable(processInstance.getId(), "key3", "value3" );
Map<String, Object> variables1 = runtimeService.getVariables(processInstance.getId());
LOGGER.info("variables1 = {}", variables1);
}
通过流程实例ID查询流程实例
@Test//通过流程实例ID查询流程实例
//启动流程前先部署流程
@org.activiti.engine.test.Deployment(resources = {"my-process.bpmn20.xml"})
public void testProcessInstanceQuery(){
RuntimeService runtimeService = activitiRule.getRuntimeService();
Map<String, Object> variables = Maps.newHashMap();
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process", variables);
LOGGER.info("processInstance = {}",processInstance);
ProcessInstance processInstance1 = runtimeService.createProcessInstanceQuery().processInstanceId(processInstance.getId()).singleResult();
LOGGER.info("processInstance = {}",processInstance1);
}
通过执行对象查询流程实例,能够获取到流程实例与执行对象
@Test//通过执行对象查询流程实例,能够获取到流程实例与执行对象
//启动流程前先部署流程
@org.activiti.engine.test.Deployment(resources = {"my-process.bpmn20.xml"})
public void testExecutionQuery(){
RuntimeService runtimeService = activitiRule.getRuntimeService();
Map<String, Object> variables = Maps.newHashMap();
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process", variables);
LOGGER.info("processInstance = {}",processInstance);
List<Execution> executionList = runtimeService.createExecutionQuery().listPage(0,100);
for(Execution execution : executionList){
LOGGER.info("execution = {}", execution);
}
}
RuntimeService中的流程触发
1.流程实例与执行流的区别
-
流程实例(ProcessInstance)表示一次工作流业务的数据实体
-
执行流(Execution)表示流程实例中具体的执行路径
-
流程实例接口继承于执行流
2.流程触发
-
使用trigger触发ReceiveTask节点
-
触发信号捕获事件sigalEventReceived(信号是全局的)
-
触发消息捕获事件messageEventReceived(消息只能针对一个流程实例发消息)
测试流程实例与执行流
流程触发trigger(ReceiveTask)runtimeService.trigger(execution.getId()); 注意:需要先将流程定义文件的userTask改为receiveTask
@Test//流程触发trigger,当触发信号发出去之后,流程执行过去,执行对象就没有了
@org.activiti.engine.test.Deployment(resources = {"my-process-trigger.bpmn20.xml"})
public void testTrigger(){
RuntimeService runtimeService = activitiRule.getRuntimeService();
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process");
Execution execution = runtimeService.createExecutionQuery().activityId("someTask").singleResult();
LOGGER.info("execution = {}", execution);
runtimeService.trigger(execution.getId());
execution = runtimeService.createExecutionQuery().activityId("someTask").singleResult();
LOGGER.info("execution = {}", execution);
}
流程触发signalEventReceived
在流程定义文件中需要先定义一个signal和intermediateCatchEvent捕获事件,后者引用这个signal
@Test//流程触发SignalEventReceived
@org.activiti.engine.test.Deployment(resources = {"my-process-signal-received.bpmn20.xml"})
public void testSignalEventReceived(){
RuntimeService runtimeService = activitiRule.getRuntimeService();
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process");
Execution execution = runtimeService.createExecutionQuery().signalEventSubscriptionName("my-signal").singleResult();
LOGGER.info("execution = {}", execution);
runtimeService.signalEventReceived("my-signal");//触发信号的时候和执行对象没有任何关系,只是发出"my-signal"信号
execution = runtimeService.createExecutionQuery().signalEventSubscriptionName("my-signal").singleResult();
LOGGER.info("execution = {}", execution);
}
流程触发messageEventReceived
此处与上述的signalEventReceived十分相似,流程定义文件中只需将signal改为message
@Test//流程触发MessageEventReceived
@org.activiti.engine.test.Deployment(resources = {"my-process-message-received.bpmn20.xml"})
public void testMessageEventReceived(){
RuntimeService runtimeService = activitiRule.getRuntimeService();
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process");
Execution execution = runtimeService.createExecutionQuery().messageEventSubscriptionName("my-message").singleResult();
LOGGER.info("execution = {}", execution);
runtimeService.messageEventReceived("my-message", execution.getId());//传入信号的时候需要将流程执行ID也传进来
execution = runtimeService.createExecutionQuery().messageEventSubscriptionName("my-message").singleResult();
LOGGER.info("execution = {}", execution);
}
基于消息启动流程
@Test//基于消息启动流程
@org.activiti.engine.test.Deployment(resources = {"my-process-message.bpmn20.xml"})
public void testMessageStart(){
RuntimeService runtimeService = activitiRule.getRuntimeService();
ProcessInstance processInstance = runtimeService.startProcessInstanceByMessage("my-message");
LOGGER.info("processInstance = {}",processInstance);
}
需要在流程定义文件中添加消息:
<message id="messageStart" name="my-message"></message>
<process id="my-process">
<startEvent id="start" >
<messageEventDefinition messageRef="messageStart" />
</startEvent>
<sequenceFlow id="flow1" sourceRef="start" targetRef="someTask" />
<userTask id="someTask" name="Activiti is awesome!" />
<sequenceFlow id="flow2" sourceRef="someTask" targetRef="end" />
<endEvent id="end" />
</process>