camunda框架学习(十)事件系列

本文详细介绍了BPMN中的消息事件,包括单消息与多消息启动事件、非终止消息边界事件、终止消息边界事件、多终止消息边界事件的使用,以及捕获消息中间事件的实现。通过代码示例展示了不同场景下的流程实例行为,解析了消息事件在流程中的生命周期和影响。同时,提到了消息事件在子流程和流程实例挂钩中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、单消息与多消息启动事件

 <bpmn:startEvent id="StartEvent_1">
      <bpmn:outgoing>Flow_0wpbzu5</bpmn:outgoing>
      <bpmn:messageEventDefinition id="MessageEventDefinition_0c1wtew" messageRef="Message_0g26tar" />
    </bpmn:startEvent>
 <bpmn:message id="Message_0g26tar" name="msg1" />

部署时候,带有消息事件,会向ACT_RU_EVENT_SUBSCR表插入数据。再次部署同一资源时:
在这里插入图片描述
消息事件启动使用:

   /**
     * select * from ACT_RU_EVENT_SUBSCR RES where (EVENT_TYPE_ = 'message') and (EVENT_NAME_ = ?) and EXECUTION_ID_ is null
     * Parameters: msg1(String)
     *
     * insert into ACT_HI_TASKINST ( ID_, PROC_DEF_KEY_, PROC_DEF_ID_, ROOT_PROC_INST_ID_, PROC_INST_ID_, EXECUTION_ID_, CASE_DEF_KEY_, CASE_DEF_ID_, CASE_INST_ID_, CASE_EXECUTION_ID_, ACT_INST_ID_, NAME_, PARENT_TASK_ID_, DESCRIPTION_, OWNER_, ASSIGNEE_, START_TIME_, END_TIME_, DURATION_, DELETE_REASON_, TASK_DEF_KEY_, PRIORITY_, DUE_DATE_, FOLLOW_UP_DATE_, TENANT_ID_, REMOVAL_TIME_ ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
     * insert into ACT_HI_PROCINST ( ID_, PROC_INST_ID_, BUSINESS_KEY_, PROC_DEF_KEY_, PROC_DEF_ID_, START_TIME_, END_TIME_, REMOVAL_TIME_, DURATION_, START_USER_ID_, START_ACT_ID_, END_ACT_ID_, SUPER_PROCESS_INSTANCE_ID_, ROOT_PROC_INST_ID_, SUPER_CASE_INSTANCE_ID_, CASE_INST_ID_, DELETE_REASON_, TENANT_ID_, STATE_ ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
     * insert into ACT_HI_ACTINST ( ID_, PARENT_ACT_INST_ID_, PROC_DEF_KEY_, PROC_DEF_ID_, ROOT_PROC_INST_ID_, PROC_INST_ID_, EXECUTION_ID_, ACT_ID_, TASK_ID_, CALL_PROC_INST_ID_, CALL_CASE_INST_ID_, ACT_NAME_, ACT_TYPE_, ASSIGNEE_, START_TIME_, END_TIME_, DURATION_, ACT_INST_STATE_, SEQUENCE_COUNTER_, TENANT_ID_, REMOVAL_TIME_ ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
     * insert into ACT_RU_EXECUTION ( ID_, ROOT_PROC_INST_ID_, PROC_INST_ID_, BUSINESS_KEY_, PROC_DEF_ID_, ACT_ID_, ACT_INST_ID_, IS_ACTIVE_, IS_CONCURRENT_, IS_SCOPE_, IS_EVENT_SCOPE_, PARENT_ID_, SUPER_EXEC_, SUPER_CASE_EXEC_, CASE_INST_ID_, SUSPENSION_STATE_, CACHED_ENT_STATE_, SEQUENCE_COUNTER_, TENANT_ID_, REV_ ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1 )
     * insert into ACT_RU_TASK ( ID_, NAME_, PARENT_TASK_ID_, DESCRIPTION_, PRIORITY_, CREATE_TIME_, OWNER_, ASSIGNEE_, DELEGATION_, EXECUTION_ID_, PROC_INST_ID_, PROC_DEF_ID_, CASE_EXECUTION_ID_, CASE_INST_ID_, CASE_DEF_ID_, TASK_DEF_KEY_, DUE_DATE_, FOLLOW_UP_DATE_, SUSPENSION_STATE_, TENANT_ID_, REV_ ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1 )
     */
    @Test
    public void startProcessInstanceByMessage() {
        String messageName = "msg1";
        runtimeService.startProcessInstanceByMessage(messageName);
    }

在这里插入图片描述

多消息:

在这里插入图片描述
在这里插入图片描述

@Test
    public void startProcessInstanceByMessage() {
        String messageName = "msg1";//或  String messageName = "msg2";
        runtimeService.startProcessInstanceByMessage(messageName);
    }

消息事件总结:
在这里插入图片描述
runtimeService.startProcessInstanceByMessage(messageName);传递的参数是消息名称,而不是消息ID

二、非终止消息边界使用

在这里插入图片描述

    <bpmn:boundaryEvent id="Event_0aqm7ex" cancelActivity="false" attachedToRef="Activity_16ubhx3">
      <bpmn:outgoing>Flow_1pp1zn9</bpmn:outgoing>
      <bpmn:messageEventDefinition id="MessageEventDefinition_1iu1dxj" messageRef="Message_0g26tar" />
    </bpmn:boundaryEvent>
  <bpmn:message id="Message_0g26tar" name="msg1" />

cancelActivity属性默认为true代表终止消息边界,false代表非终止消息边界

  /非终止消息边界事件
    @Test
    public void createDeploymentBoundaryEvent() {
        DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
        Deployment deployment = deploymentBuilder
                .name("非终止消息边界事件")
                .source("本地测试")
                .tenantId("a")
                .addClasspathResource("com.demo/ch14/msg_boundaryevent.bpmn")
                .deploy();

        System.out.println(deploymentBuilder);
        System.out.println(deployment);
    }

    @Test
    public void startProcessInstanceByKey2() {
        runtimeService.startProcessInstanceByKey("msg");
    }

    /**
     * insert into ACT_HI_ACTINST ( ID_, PARENT_ACT_INST_ID_, PROC_DEF_KEY_, PROC_DEF_ID_, ROOT_PROC_INST_ID_, PROC_INST_ID_, EXECUTION_ID_, ACT_ID_, TASK_ID_, CALL_PROC_INST_ID_, CALL_CASE_INST_ID_, ACT_NAME_, ACT_TYPE_, ASSIGNEE_, START_TIME_, END_TIME_, DURATION_, ACT_INST_STATE_, SEQUENCE_COUNTER_, TENANT_ID_, REMOVAL_TIME_ ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
     * insert into ACT_RU_EXECUTION ( ID_, ROOT_PROC_INST_ID_, PROC_INST_ID_, BUSINESS_KEY_, PROC_DEF_ID_, ACT_ID_, ACT_INST_ID_, IS_ACTIVE_, IS_CONCURRENT_, IS_SCOPE_, IS_EVENT_SCOPE_, PARENT_ID_, SUPER_EXEC_, SUPER_CASE_EXEC_, CASE_INST_ID_, SUSPENSION_STATE_, CACHED_ENT_STATE_, SEQUENCE_COUNTER_, TENANT_ID_, REV_ ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1 )
     * insert into ACT_RU_TASK ( ID_, NAME_, PARENT_TASK_ID_, DESCRIPTION_, PRIORITY_, CREATE_TIME_, OWNER_, ASSIGNEE_, DELEGATION_, EXECUTION_ID_, PROC_INST_ID_, PROC_DEF_ID_, CASE_EXECUTION_ID_, CASE_INST_ID_, CASE_DEF_ID_, TASK_DEF_KEY_, DUE_DATE_, FOLLOW_UP_DATE_, SUSPENSION_STATE_, TENANT_ID_, REV_ ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1 )
     * update ACT_RU_EXECUTION set REV_ = ?, PROC_DEF_ID_ = ?, BUSINESS_KEY_ = ?, ACT_ID_ = ?, ACT_INST_ID_ = ?, IS_ACTIVE_ = ?, IS_CONCURRENT_ = ?, IS_SCOPE_ = ?, IS_EVENT_SCOPE_ = ?, PARENT_ID_ = ?, SUPER_EXEC_ = ?, SUSPENSION_STATE_ = ?, CACHED_ENT_STATE_ = ?, SEQUENCE_COUNTER_ = ?, TENANT_ID_ = ? where ID_ = ? and REV_ = ?
     */
    @Test
    public void messageEventReceived() {
        String messageName = "msg1";
        String executionId = "103";
        runtimeService.messageEventReceived(messageName, executionId);
    }

    @Test
    public void complete() {
        taskService.complete("606");
    }
    /非终止消息边界事件
示例一:

1、启动流程:当流程实例走到任务1节点,任务表中有”任务1“节点数据。实例表会产生两条数据。消息订阅表产生数据
在这里插入图片描述
2、发送消息信号”messageName“:任务表增加了一条任务数据”任务3“,实例表会产生两条数据
在这里插入图片描述
3、完成”任务3“:关于”任务3“的执行实例以及任务被删除了,只留下了发送消息之前的两条执行实例
在这里插入图片描述
4、完成”任务1“节点:消息订阅表数据被清理,任务表及执行表中只有”任务2“的任务节点数据
在这里插入图片描述
5、再完成“任务2”,整个实例结束

示例二:

1、再次启动实例,直接完成”任务1“:直接到达任务2,相当于示例1中的步骤4

2、再完成“任务2”,整个实例结束

总结:非终止消息边界,生命周期与当前节点一致,当当前节点(任务1)被完成后,消息周期也随之结束

三、终止消息边界

<bpmn:message id="Message_0g26tar" name="msg1" />
    <bpmn:boundaryEvent id="Event_0aqm7ex" attachedToRef="Activity_16ubhx3">
      <bpmn:outgoing>Flow_1pp1zn9</bpmn:outgoing>
      <bpmn:messageEventDefinition id="MessageEventDefinition_0mc449v" />
    </bpmn:boundaryEvent>

cancelActivity="true"为默认,可以不写

示例一:

1、启动流程,当走到“任务1”节点时,任务表中有“任务1”节点数据,实例表中产生两条数据,消息订阅表产生数据
在这里插入图片描述
2、发送消息信号”messageName“:任务表增加了一条任务数据”任务3“,“任务1被删除”,实例表中只剩一条数据,消息订阅表被清理。
在这里插入图片描述
3、再完成“任务3”,整个实例结束

总结:终止边界,会终止其关联的节点,即PARENT

四、多终止消息边界使用

在这里插入图片描述
两个终止边界,注:两个终止消息边界,不能对应同一个消息

  <bpmn:message id="Message_0g26tar" name="msg1" />
  <bpmn:message id="Message_1arfymh" name="msg2" />
    <bpmn:boundaryEvent id="Event_0aqm7ex" attachedToRef="Activity_16ubhx3">
      <bpmn:outgoing>Flow_1pp1zn9</bpmn:outgoing>
      <bpmn:messageEventDefinition id="MessageEventDefinition_0mc449v" messageRef="Message_1arfymh" />
    </bpmn:boundaryEvent>
    <bpmn:boundaryEvent id="Event_091m04g" attachedToRef="Activity_16ubhx3">
      <bpmn:outgoing>Flow_0p2awff</bpmn:outgoing>
      <bpmn:messageEventDefinition id="MessageEventDefinition_1en3rvi" messageRef="Message_0g26tar" />
    </bpmn:boundaryEvent>
示例一:

1、启动任务,执行实例有两条数据,任务表有“任务1”,订阅消息表有两个:msg1msg2

2、直接完成“任务1”,消息订阅表被清理,任务只有“任务2”,执行实例只剩一条数据

3、完成“任务2”,实例结束

不管是用消息1还是消息2做查询执行实例操作,都可以查询到同一个执行实例
在这里插入图片描述

示例二:

1、启动任务,执行实例有两条数据,任务表有“任务1”,消息订阅表有两个:msg1msg2

2、发射消息msg1的信号,任务只剩“任务4”,消息订阅表被清理,执行实例只剩一条数据

3、完成“任务4”,实例结束
在这里插入图片描述
使用变量定义消息:

    <bpmn:boundaryEvent id="Event_0aqm7ex" attachedToRef="Activity_16ubhx3">
      <bpmn:outgoing>Flow_1pp1zn9</bpmn:outgoing>
      <bpmn:messageEventDefinition id="MessageEventDefinition_0mc449v" messageRef="Message_1arfymh" />
    </bpmn:boundaryEvent>
    <bpmn:boundaryEvent id="Event_091m04g" attachedToRef="Activity_16ubhx3">
      <bpmn:outgoing>Flow_0p2awff</bpmn:outgoing>
      <bpmn:messageEventDefinition id="MessageEventDefinition_1en3rvi" messageRef="Message_0g26tar" />
    </bpmn:boundaryEvent>
  <bpmn:message id="Message_0g26tar" name="msg-${a}" />
  <bpmn:message id="Message_1arfymh" name="msg-${b}" />
    @Test
    public void startProcessInstanceByKey5() {
        Map<String, Object> vars = new HashMap<>();
        vars.put("a", "msg1");
        vars.put("b", "msg2");
        runtimeService.startProcessInstanceByKey("msg",vars);
    }

在这里插入图片描述

五、非终止消息边界与终止消息边界的区别

在这里插入图片描述
在这里插入图片描述

六、捕获消息中间事件

在这里插入图片描述

    <bpmn:intermediateCatchEvent id="Event_1dnn0s4">
      <bpmn:incoming>Flow_1plc99x</bpmn:incoming>
      <bpmn:outgoing>Flow_0h8n1v3</bpmn:outgoing>
      <bpmn:messageEventDefinition id="MessageEventDefinition_061cuy9" messageRef="Message_0g26tar" />
    </bpmn:intermediateCatchEvent>
  <bpmn:message id="Message_0g26tar" name="msg1" />

类似于Java中的try...catch,启动改流程实例的时候,实例会逗留在捕获消息中间事件,不会流转到“任务1”

使用messageEventReceived发射消息,则实例继续往下流程,事件订阅数据也随之删除,捕获消息中间时间与实例挂钩,与流程定义关系不大

抛出消息事件:

在这里插入图片描述

在这里插入图片描述

    <bpmn:intermediateThrowEvent id="Event_1dnn0s4">
      <bpmn:incoming>Flow_1plc99x</bpmn:incoming>
      <bpmn:outgoing>Flow_0h8n1v3</bpmn:outgoing>
      <bpmn:messageEventDefinition id="MessageEventDefinition_054hcn1" messageRef="Message_0g26tar" camunda:class="com.demo.ch14.PengSendTaskJavaDelegate" />
    </bpmn:intermediateThrowEvent>

  <bpmn:message id="Message_0g26tar" name="msg1" />
public class PengSendTaskJavaDelegate implements JavaDelegate {

    public static boolean wasExecuted = false;

    @Override
    public void execute(DelegateExecution delegateExecution) throws Exception {

        wasExecuted = true;
    }
}
    @Test
    public void startProcessInstanceByKey() {
        runtimeService.startProcessInstanceByKey("msg");
    }

启动流程时,便会走到PengSendTaskJavaDelegate类中的execute方法
抛出消息中间事件,在子流程中用的比较多

代码参考:https://github.com/zhoupengwa/ProcessEngineDemo

学习来源:腾讯课堂

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值