消息事件与信号事件非常像,事件的类型、触发的方式都非常像,唯一的区别是信号事件是广播,执行的时候只有一个参数,就是信号名称,而 消息事件 它有两个参数,分别是消息名称和流程实例id,就是说消息事件每一次的作用域只能是一个流程实例,信号事件就像是:大喊一声,所以的人(流程实例)都能听到,而消息事件,就像是打电话给某一个人。

消息事件典型应用

  • 跨实例进行触发
  • 跨任务进行触发

对应消息事件,常用的一个场景:就是撤回任务,撤回的功能,我们有多中实现方式:比如使用代码的方式直接删除数据,清理数据很近,但是用 消息事件就非常方便

消息事件类型

image.png

  • 消息启动事件
  • 消息边界事件
  • 消息中间事件
  • 消息非中断事件

    绘制流程

    image.png
    image.png
    image.png
    image.png

    取回任务-测试

    image.png
    image.png

    消息的数据存储在哪个表里呢?

    1. -- 消息表
    2. select * from act_ru_event_subscr
    ```xml <?xml version=”1.0” encoding=”UTF-8”?>
    <bpmn2:outgoing>Flow_068r59u</bpmn2:outgoing>
    
    <bpmn2:incoming>Flow_068r59u</bpmn2:incoming>
    <bpmn2:incoming>Flow_02v8rjd</bpmn2:incoming>
    <bpmn2:outgoing>Flow_0cwpact</bpmn2:outgoing>
    
    <bpmn2:incoming>Flow_0cwpact</bpmn2:incoming>
    <bpmn2:outgoing>Flow_09p9z8c</bpmn2:outgoing>
    
    <bpmn2:incoming>Flow_09p9z8c</bpmn2:incoming>
    
    <bpmn2:outgoing>Flow_02v8rjd</bpmn2:outgoing>
    <bpmn2:messageEventDefinition id="MessageEventDefinition_13veose" messageRef="Message_0jnnf54" />
    
    <bpmndi:BPMNEdge id="Flow_02v8rjd_di" bpmnElement="Flow_02v8rjd">
      <di:waypoint x="440" y="328" />
      <di:waypoint x="440" y="348" />
      <di:waypoint x="310" y="348" />
      <di:waypoint x="310" y="310" />
    </bpmndi:BPMNEdge>
    <bpmndi:BPMNEdge id="Flow_09p9z8c_di" bpmnElement="Flow_09p9z8c">
      <di:waypoint x="480" y="270" />
      <di:waypoint x="542" y="270" />
    </bpmndi:BPMNEdge>
    <bpmndi:BPMNEdge id="Flow_0cwpact_di" bpmnElement="Flow_0cwpact">
      <di:waypoint x="320" y="270" />
      <di:waypoint x="380" y="270" />
    </bpmndi:BPMNEdge>
    <bpmndi:BPMNEdge id="Flow_068r59u_di" bpmnElement="Flow_068r59u">
      <di:waypoint x="168" y="270" />
      <di:waypoint x="220" y="270" />
    </bpmndi:BPMNEdge>
    <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
      <dc:Bounds x="132" y="252" width="36" height="36" />
    </bpmndi:BPMNShape>
    <bpmndi:BPMNShape id="Activity_0vc4r8t_di" bpmnElement="Activity_0vc4r8t">
      <dc:Bounds x="220" y="230" width="100" height="80" />
    </bpmndi:BPMNShape>
    <bpmndi:BPMNShape id="Activity_0ddo8bc_di" bpmnElement="Activity_0ddo8bc">
      <dc:Bounds x="380" y="230" width="100" height="80" />
    </bpmndi:BPMNShape>
    <bpmndi:BPMNShape id="Event_0ciubl2_di" bpmnElement="Event_0ciubl2">
      <dc:Bounds x="542" y="252" width="36" height="36" />
    </bpmndi:BPMNShape>
    <bpmndi:BPMNShape id="Event_1j7o3sq_di" bpmnElement="Event_0f0ygx1">
      <dc:Bounds x="422" y="292" width="36" height="36" />
    </bpmndi:BPMNShape>
    
![image.png](https://cdn.nlark.com/yuque/0/2020/png/1511608/1604842462540-e10cd458-7b5e-46e2-8fb8-59da93080a11.png#align=left&display=inline&height=75&margin=%5Bobject%20Object%5D&name=image.png&originHeight=150&originWidth=751&size=63840&status=done&style=none&width=375.5)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/1511608/1604842598342-49b3b314-3944-4ab7-bdd5-f4d237c455f1.png#align=left&display=inline&height=124&margin=%5Bobject%20Object%5D&name=image.png&originHeight=247&originWidth=1324&size=44621&status=done&style=none&width=662)
```java
package com.torey.activiti7_workflow;

import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.Execution;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class Part10_EventAndTask {
    @Autowired
    private RuntimeService runtimeService;

    /**
     * 消息撤回代码
     */
    @Test
    public void msgBack(){
        String msgName="Message_0u3ougp";
        Execution execution = runtimeService.createExecutionQuery()
                .messageEventSubscriptionName(msgName) //消息的名称
                .processInstanceId("e83dde7f-21c3-11eb-b32b-603a7c6bd5e8") //流程实例id
                .singleResult();
        //有三个参数,第一个是 消息的名称,第二个是 执行节点的id, 第三参数是 流程的变量
        //发送消息
        runtimeService.messageEventReceived(msgName,execution.getId());
    }
}

注意,可以跨节点撤回

可以跨节点撤回,但必须要记住 要撤回到哪了的 节点编号 和 消息名称,可以在监听器,将 节点编号 和 消息名称 写入到字段注入里,
image.png