一、单消息与多消息启动事件
<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”,订阅消息表有两个:msg1
、msg2
2、直接完成“任务1”,消息订阅表被清理,任务只有“任务2”,执行实例只剩一条数据
3、完成“任务2”,实例结束
不管是用消息1还是消息2做查询执行实例操作,都可以查询到同一个执行实例
示例二:
1、启动任务,执行实例有两条数据,任务表有“任务1”,消息订阅表有两个:msg1
、msg2
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
学习来源:腾讯课堂