Activiti6.0学习实践(7)-核心api:RuntimeService流程运行控制服务

RuntimeService是流程引擎中的流程运行控制服务,主要提供了以下功能:

  1. 启动流程及对流程数据的控制
  2. 流程实例(ProcessInstance)与执行流(Exceution)查询
  3. 触发流程操作、接收消息和信号

RuntimeService启动流程的常用方式(id,key,message),可选参数(businessKey,variables,tenantid),可以对变量进行设置和获取(是流程实例级别的,还是流程实例级别),下面通过一个测试代码来了解RuntimeService的各种接口

1、创建一个测试类RuntimeServiceTest

public class RuntimeServiceTest {
    private static final Logger logger = LoggerFactory.getLogger(RuntimeServiceTest.class);


    @Rule
    public ActivitiRule activitiRule = new ActivitiRule();

    @Test
    public void test() {
   
    }

 2、流程启动

流程的启动有三种方式,分别是通过key,id,builder的方式进行启动

2.1 首先是通过key的方式ey的方式
 

@Test
@Deployment(resources = {"my-process.bpmn20.xml"})
public void testStartByKey() {
    //获取runtimeService
    RuntimeService runtimeService = activitiRule.getRuntimeService();
    //设置一下流程的key
    Map<String, Object> variables = Maps.newHashMap();
    variables.put("key1","value1");

    //通过key方式启动流程实例。(流程多次启动id不同,但是key 不会变)
    ProcessInstance processInstance
            = runtimeService.startProcessInstanceByKey("my-process", variables);
    logger.info("processInstance = {}, key={}", processInstance, processInstance.getProcessDefinitionKey());

}

执行日志如下:

2.2 通过id的方式

@Test
@Deployment(resources = {"my-process.bpmn20.xml"})
public void testStartById() {
    //获取runtimeService
    RuntimeService runtimeService = activitiRule.getRuntimeService();
    //通过流程定义对象获取流程id,这里会涉及使用流程的存储服务repositoryservice
    ProcessDefinition processDefinition
            = activitiRule.getRepositoryService().createProcessDefinitionQuery().singleResult();

    //设置一下流程的key
    Map<String, Object> variables = Maps.newHashMap();
    variables.put("key1","value1");

    //通过key方式启动流程实例。(流程多次启动id不同,但是key 不会变)
    ProcessInstance processInstance
            = runtimeService.startProcessInstanceById(processDefinition.getId(), variables);
    logger.info("processInstance = {}, key={}, id={}" , processInstance, processInstance.getProcessDefinitionKey(), processInstance.getId());

}

执行日志:

2.3 通过构建者builder启动

@Test
@Deployment(resources = {"my-process.bpmn20.xml"})
public void testProcessInstanceBuilder() {
    //获取runtimeService
    RuntimeService runtimeService = activitiRule.getRuntimeService();
    //设置一下流程的key
    Map<String, Object> variables = Maps.newHashMap();
    variables.put("key1","value1");

    //通过流程实例构建者进行流程启动
    ProcessInstanceBuilder processInstanceBuilder = runtimeService.createProcessInstanceBuilder();
    ProcessInstance processInstance = processInstanceBuilder.businessKey("businesskey0001")
            .processDefinitionKey("my-process")
            .variables(variables)
            .start();

    logger.info("processInstance = {}, key={}", processInstance, processInstance.getProcessDefinitionKey());

}

执行日志如下:

可以看到以上几种方式启动是没有什么差别的。

3、流程变量

可以通过设置变量的方式,使得流程可以携带数据(变量)进行流转。在流转的过程中,可以对流程变量进行修改和新增

//这段测试代码,对流程变量进行测试,包含变量的设置,新增,修改
@Test
@Deployment(resources = {"my-process.bpmn20.xml"})
public void testVariables() {
    //获取runtimeService
    RuntimeService runtimeService = activitiRule.getRuntimeService();
    //设置一下流程的key
    Map<String, Object> variables = Maps.newHashMap();
    variables.put("key1","value1");
    variables.put("key2","value2");


    //通过key方式启动流程实例。(流程多次启动id不同,但是key 不会变)
    ProcessInstance processInstance
            = runtimeService.startProcessInstanceByKey("my-process", variables);
    logger.info("processInstance = {}, key={}", processInstance, processInstance.getProcessDefinitionKey());

    //修改变量内容
    runtimeService.setVariable(processInstance.getId(), "key3","value3");  //新增key
    runtimeService.setVariable(processInstance.getId(), "key2","value2-2"); //修改key值

    //获取变量
    Map<String, Object> variables1 = runtimeService.getVariables(processInstance.getId());
    logger.info("varialbles1 = {}", variables1);

}

执行日志:

4、流程执行流(execution)

首先要说明一下流程执行流和流程实例的关系:流程执行流表示流程实例中具体的执行路径,流程实例是一次工作流业务的数据实体。可以从流程实例的类定义可以看到,流程实例是继承于流程执行流的。

下面是流程执行流的一个例子:

//流程实例的查询
@Test
@Deployment(resources = {"my-process.bpmn20.xml"})
public void testProcessInstanceQuery() {
    //获取runtimeService
    RuntimeService runtimeService = activitiRule.getRuntimeService();
    //设置一下流程的key
    Map<String, Object> variables = Maps.newHashMap();
    variables.put("key1","value1");

    //通过key方式启动流程实例。(流程多次启动id不同,但是key 不会变),启动后如果不停止,流程没有结束,处于等待状态
    ProcessInstance processInstance
            = runtimeService.startProcessInstanceByKey("my-process", variables);
    logger.info("processInstance = {}, key={}", processInstance, processInstance.getProcessDefinitionKey());

    //通过流程运行时服务获取执行对象
    List<Execution> executions = runtimeService.createExecutionQuery()
            .listPage(0, 100);
    for (Execution execution : executions) {
        logger.info("execution ={}", execution);
    }
}

执行结果如下:

5、流程触发trigger

流程执行过程中,可以通过trigger来触发流程接收事件或者消息进行流程的执行。我们通过下面的例子来演示:

首先创建一个新的bpmn文件,这个文件中将usertask替换为receiveTask,这个任务会进行触发消息或者事件的捕捉

<?xml version="1.0" encoding="UTF-8"?>

<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"
   xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
   xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema"
   expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">

   <process id="my-process">

      <startEvent id="start" />
      <sequenceFlow id="flow1" sourceRef="start" targetRef="someTask" />
      
<!--      <userTask id="someTask" name="Activiti is awesome!" />-->
      <receiveTask id="someTask" name="Activiti is awesome!" />
      <sequenceFlow id="flow2" sourceRef="someTask" targetRef="end" />

      <endEvent id="end" />

   </process>

</definitions>

然后我们在测试代码中这样进行触发;

//通过trigger来控制流程的执行
@Test
@Deployment(resources = {"my-process-trigger.bpmn20.xml"})
public void testTrigger() {
    //获取runtimeService
    RuntimeService runtimeService = activitiRule.getRuntimeService();

    //通过key方式启动流程实例。(流程多次启动id不同,但是key 不会变)
    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);

}

执行结果:

从日志看,第一次打印出执行流的信息,然后trigger触发后,流程继续执行结束,这个时候执行流结束了,所以第二次打印的是null

6、通过信号事件触发

流程执行也可以通过信号事件触发,下面例子就是一个通过信号事件触发的demo

首先也是需要构造一下流程定义文件,注意其中signalEventDefinition的属性定义

<?xml version="1.0" encoding="UTF-8"?>

<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"
   xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
   xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema"
   expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
   <signal id="signalStart"  name="my-signal"></signal>
   <process id="my-process">

      <startEvent id="start" />
      <sequenceFlow id="flow1" sourceRef="start" targetRef="signal-received" />
      <intermediateCatchEvent id="signal-received">
         <signalEventDefinition  signalRef="signalStart"> </signalEventDefinition>
      </intermediateCatchEvent>

      <sequenceFlow id="flow2" sourceRef="signal-received" targetRef="end" />

      <endEvent id="end" />

   </process>

</definitions>

测试代码如下:


//通过信号来触发流程的执行
@Test
@Deployment(resources = {"my-process-signal.bpmn20.xml"})
public void testSignalEventReceived() {
    //获取runtimeService
    RuntimeService runtimeService = activitiRule.getRuntimeService();

    //通过key方式启动流程实例。(流程多次启动id不同,但是key 不会变)
    ProcessInstance processInstance
            = runtimeService.startProcessInstanceByKey("my-process");

    //查找一下是否有等待触发的信号
    Execution execution = runtimeService.createExecutionQuery().signalEventSubscriptionName("my-signal")
            .singleResult();
    logger.info("execution = {}", execution);

    runtimeService.signalEventReceived ("my-signal");
    execution = runtimeService.createExecutionQuery().signalEventSubscriptionName("my-signal")
            .singleResult();
    logger.info("execution = {}", execution);

}

流程启动后等待信号触发,在发出信号后,流程执行流执行完成。

7、通过消息触发

下面学习一下如何通过消息进行触发

首先建立一个配置文件,配置用消息进行触发

注意图中的标红框处内容,具体测试函数如下:

//通过消息来触发流程的执行
@Test
@Deployment(resources = {"my-process-message.bpmn20.xml"})
public void testMessageReceived() {
    //获取runtimeService
    RuntimeService runtimeService = activitiRule.getRuntimeService();

    //通过key方式启动流程实例。(流程多次启动id不同,但是key 不会变)
    ProcessInstance processInstance
            = runtimeService.startProcessInstanceByKey("my-process");

    //查找一下是否有等待触发的信号
    Execution execution = runtimeService.createExecutionQuery().messageEventSubscriptionName ("my-message")
            .singleResult();
    logger.info("execution = {}", execution);

    runtimeService.messageEventReceived ("my-message",execution.getId());
    execution = runtimeService.createExecutionQuery().messageEventSubscriptionName("my-message")
            .singleResult();
    logger.info("execution = {}", execution);

}

执行日志:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值