【Activiti系列学习】--14.Activiti核心API之RuntimeService

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>
发布了66 篇原创文章 · 获赞 32 · 访问量 8531

猜你喜欢

转载自blog.csdn.net/shao_yc/article/details/105328147