Activiti6.0流程引擎学习——(21)activiti的流程运行控制服务(RuntimeService)【2】

接着上篇继续介绍activiti的流程运行控制服务。

流程实例与执行流:

1、流程实例(ProcessInstance)表示一次工作流业务的数据实体;

2、执行流(Execution)表示流程实例汇总具体的执行路径;

3、流程实例接口(ProcessInstance)继承了执行流(Execution),流程实例在执行流的基础上扩展了一些其他系列的操作。

 

流程触发:

1、使用trigger触发ReceiveTask节点,当流程执行到这个Task节点的时候就会暂停下来,等待需要接受的事件去执行;

2、触发信号捕获事件signalEventReceived,当只有获取这个信号以后才能继续执行;

3、触发消息捕获事件messageEventReceived,只有捕获到某些消息后才能继续执行。

注:这里触发信号与触发消息非常相似,但是信号是可以全局发送信号,消息只能针对某个流程实例发送消息。


接下来我们来测试一下:

一、流程触发trigger

首先只是为了测试,所以我们使用一个简单的流程图:

然后用代码演示一下执行效果:

先要定义并且设计如上一样的流程图,创建my-process-trigger.bpmn20.xml流程文件:

my-process-trigger.bpmn20.xml文件中内容如下:

<?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" />

		<receiveTask id="someTask"/>  <!--使用receiveTask-->
		<sequenceFlow id="flow2" sourceRef="someTask" targetRef="end" />

		<endEvent id="end" />

	</process>

</definitions>

然后在上一篇创建的RuntimeServiceTest测试类中新增测试函数:

    /**
     * 流程触发trigger
     */
    @Test
    @org.activiti.engine.test.Deployment(resources = "my-process-trigger.bpmn20.xml")
    public void testTrigger(){
        RuntimeService runtimeService = activitiRule.getRuntimeService();
        ProcessInstance processInstance = runtimeService
                .startProcessInstanceByKey("my-process");//通过流程图中的<process id="my-process">来启动流程

        Execution execution = runtimeService.createExecutionQuery()
                .activityId("someTask").singleResult();   //获取执行流对象,someTask是其中事件的id
        LOGGER.info("execution = [{}]" , execution);

        runtimeService.trigger(execution.getId());   //获取这个的id来触发执行
        execution = runtimeService.createExecutionQuery()
                .activityId("someTask").singleResult();     //重新获取someTask
        LOGGER.info("execution = [{}]" , execution);    //重新打印
    }

测试结果:

Loading XML bean definitions from class path resource [activiti.cfg.xml]
Activiti 5 compatibility handler implementation not found or error during instantiation : org.activiti.compatibility.DefaultActiviti5CompatibilityHandler. Activiti 5 backwards compatibility disabled.
performing create on engine with resource org/activiti/db/create/activiti.h2.create.engine.sql
performing create on history with resource org/activiti/db/create/activiti.h2.create.history.sql
performing create on identity with resource org/activiti/db/create/activiti.h2.create.identity.sql
ProcessEngine default created
execution = [Execution[ id '5' ] - activity 'someTask - parent '4']
execution = [null]

可以看到我们第一次输出execution时可以获取到执行流对象 Execution[ id '5' ] - activity 'someTask - parent '4'。当触发信号发出去以后,流程执行过去则第二次输出execution时这个执行对象就已经没有了,也就是后面的null。

 

二、流程触发Signal信号事件

这里使用流程图如下:

创建my-process-signal-received.bpmn20.xml流程文件,其中xml流程文件内容:

<?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">   <!-- 捕获事件,当接收到上面定义的my-signal信号才继续向下执行 -->
			<signalEventDefinition signalRef="signalStart"/>
		</intermediateCatchEvent>
		
		<sequenceFlow id="flow2" sourceRef="signal-received" targetRef="end" />

		<endEvent id="end" />

	</process>

</definitions>

在RuntimeServiceTest测试类中新增测试函数:

    /**
     * 测试流程触发的 signalEventReceived  信号捕获
     */
    @Test
    @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");//通过流程图中的<process id="my-process">来启动流程

        Execution execution = runtimeService.createExecutionQuery()
                .signalEventSubscriptionName("my-signal").singleResult();   //获取执行流对象,my-signal是其中信号
        LOGGER.info("execution = [{}]" , execution);

        //来触发我们定义的信号,发出一个my-signal的信号,若不是这个信号则下面输出还停留在signal-received这一步
        runtimeService.signalEventReceived("my-signal");


        execution = runtimeService.createExecutionQuery()
                .signalEventSubscriptionName("my-signal").singleResult();
        LOGGER.info("execution = [{}]" , execution);    //重新打印
    }

输出结果:

Loading XML bean definitions from class path resource [activiti.cfg.xml]
Activiti 5 compatibility handler implementation not found or error during instantiation : org.activiti.compatibility.DefaultActiviti5CompatibilityHandler. Activiti 5 backwards compatibility disabled.
performing create on engine with resource org/activiti/db/create/activiti.h2.create.engine.sql
performing create on history with resource org/activiti/db/create/activiti.h2.create.history.sql
performing create on identity with resource org/activiti/db/create/activiti.h2.create.identity.sql
ProcessEngine default created
execution = [Execution[ id '5' ] - activity 'signal-received - parent '4']
execution = [null]

 

三、流程触发messageEventReceived

信号与具体流程实例没有关系,但是这里的消息必须指定流程执行对象的ID才能继续执行。

测试流程图如下:

创建my-process-message-received.bpmn20.xml流程文件,xml流程文件内容:

<?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">

	<message id="messageStart" name="my-message"></message>
	<process id="my-process">

		<startEvent id="start" />
		<sequenceFlow id="flow1" sourceRef="start" targetRef="message-received" />

		<intermediateCatchEvent id="message-received">
			<messageEventDefinition messageRef="messageStart"/>
		</intermediateCatchEvent>
		
		<sequenceFlow id="flow2" sourceRef="message-received" targetRef="end" />

		<endEvent id="end" />

	</process>

</definitions>

在RuntimeServiceTest测试类中新增测试函数:

     /**
     * 测试事件触发的 messageEventReceived  信号捕获
     */
    @Test
    @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");//通过流程图中的<process id="my-process">来启动流程

        Execution execution = runtimeService.createExecutionQuery()
                .messageEventSubscriptionName("my-message").singleResult();   //获取执行流对象,my-message是消息
        LOGGER.info("execution = [{}]" , execution);

        runtimeService.messageEventReceived("my-message",execution.getId());   //将流程执行ID作为参数传进去


        execution = runtimeService.createExecutionQuery()
                .messageEventSubscriptionName("my-message").singleResult();
        LOGGER.info("execution = [{}]" , execution);    //重新打印
    }

输出结果:

Loading XML bean definitions from class path resource [activiti.cfg.xml]
Activiti 5 compatibility handler implementation not found or error during instantiation : org.activiti.compatibility.DefaultActiviti5CompatibilityHandler. Activiti 5 backwards compatibility disabled.
performing create on engine with resource org/activiti/db/create/activiti.h2.create.engine.sql
performing create on history with resource org/activiti/db/create/activiti.h2.create.history.sql
performing create on identity with resource org/activiti/db/create/activiti.h2.create.identity.sql
ProcessEngine default created
execution = [Execution[ id '5' ] - activity 'message-received - parent '4']
execution = [null]

 

四、基于message启动流程

创建my-process-message.bpmn20.xml流程文件,其中流程内容如下:

<?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">

	<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>

</definitions>

RuntimeServiceTest测试类中的测试函数:

    /**
     * 基于message启动流程
     */
    @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");  //通过流程图中的 <message id="messageStart" name="my-message"></message> 来启动流程

        LOGGER.info("processInstance = [{}]", processInstance);
    }

输出结果:

可以看到基于message也可以正常启动流程实例。

基于key启动与message启动的区别?

基于key启动更为简洁,基于message启动则有点繁琐,需要在流程定义文件里面定义一个message标签。并且得到的ProcessInstance[5],key则是ProcessInstance[4]。因为基于message启动会在数据库的表中插入一条记录,所以就变成了5。启动过程是根据message信号从事件订阅中找到订阅这个信号的id,最后找到流程定义的key然后启动。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青山孤客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值