BPMN中的事件分類方式包括以下三種:
(1). 位置分類:開始事件、中間事件 | 邊界事件儿咱、結(jié)束事件颁独。
(2). 特性分類:捕獲事件(Catching)、拋出事件(Throwing)吨枉。
(3). 事件定義分類:定時(shí)事件蹦渣、錯(cuò)誤事件、信號(hào)事件貌亭、消息事件柬唯。
- 定時(shí)事件
* 指定事件(timeDate)
* 指定持續(xù)時(shí)間(timeDuration)
* 周期執(zhí)行(timeCycle)
<timerEventDefinition>
<timeDate>2020-04-27T10:10:10</timeDate>
</timerEventDefinition>
(1)定時(shí)開始事件
定時(shí)開始事件
<startEvent id="start" >
<timerEventDefinition>
<timeDate>2020-04-27T10:10:10</timeDate>
</timerEventDefinition>
</startEvent>
(2)定時(shí)邊界事件
定時(shí)邊界事件
<userTask id="someTask"/>
<boundaryEvent attachedToRef="somtTask" id="timeOutEvent"
cancelActivity="true">
<timerEventDefinition>
<timeDate>2020-04-27T10:10:10</timeDate>
</timerEventDefinition>
</boundaryEvent>
??定時(shí)邊界事件實(shí)戰(zhàn):
??(1)首先修改配置文件,啟動(dòng)異步執(zhí)行開關(guān)和執(zhí)行日志圃庭。
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration">
<property name="asyncExecutorActivate" value="true"></property>
<property name="enableVerboseExecutionTreeLogging" value="true"></property>
</bean>
??(2)編寫流程定義文件锄奢。
<process id="my-process">
<startEvent id="start" />
<sequenceFlow id="flow1" sourceRef="start" targetRef="userTask"/>
<!--定義阻塞的用戶任務(wù)-->
<userTask id="userTask" name="阻塞task"/>
<sequenceFlow id="flow2" sourceRef="userTask" targetRef="end" />
<!--如果5秒內(nèi)沒有執(zhí)行,將會(huì)觸發(fā)邊界事件-->
<boundaryEvent attachedToRef="userTask" id="timeEvent" cancelActivity="true">
<timerEventDefinition>
<timeDuration>PT5S</timeDuration>
</timerEventDefinition>
</boundaryEvent>
<!--如果5秒內(nèi)沒有執(zhí)行剧腻,將會(huì)跳轉(zhuǎn)到 timeOutTask-->
<sequenceFlow sourceRef="timeEvent" targetRef="timeOutNode"></sequenceFlow>
<sequenceFlow sourceRef="timeOutNode" targetRef="end"></sequenceFlow>
<userTask id="timeOutNode" name="超時(shí)task"></userTask>
<endEvent id="end" />
</process>
??(3)編寫測(cè)試類進(jìn)行測(cè)試:
@Rule
public ActivitiRule activitiRule = new ActivitiRule();
@Test
@Deployment(resources = "my-process.bpmn20.xml")
public void test() throws InterruptedException {
ProcessInstance processInstance = activitiRule.getRuntimeService().startProcessInstanceByKey("my-process");
Task task = activitiRule.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
logger.info("當(dāng)前的任務(wù)節(jié)點(diǎn)為 = {}", task.getName());
Thread.sleep(1000 * 10);
task = activitiRule.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
logger.info("當(dāng)前的任務(wù)節(jié)點(diǎn)為 = {}", task.getName());
}
-
錯(cuò)誤事件
執(zhí)行流程
??錯(cuò)誤事件用來處理業(yè)務(wù)流程中出現(xiàn)的異常拘央。
<endEvent id="errorEvent" name="End">
<errorEventDefinition errorRef="customError"></errorEventDefinition>
</endEvent>
(1)錯(cuò)誤邊界事件
執(zhí)行流程
??在流程定義文件的子流程中,可以判斷附件是否滿足要求书在,比如是否有用戶能夠處理此次流程灰伟,如果不滿足則跳轉(zhuǎn)到一個(gè)錯(cuò)誤事件節(jié)點(diǎn),錯(cuò)誤邊界事件會(huì)捕獲到該事件儒旬,然后將流程跳轉(zhuǎn)到處理錯(cuò)誤的用戶任務(wù)中袱箱。
//1. 當(dāng)附加信息不夠時(shí)遏乔,流程跳轉(zhuǎn)到噶節(jié)點(diǎn)。
<endEvent id="errorEvent" name="End">
<errorEventDefinition errorRef="notEnoughInfo"></errorEventDefinition>
</endEvent>
//2. 進(jìn)行捕獲发笔,通過sequenceFlow節(jié)點(diǎn)跳轉(zhuǎn)到處理錯(cuò)誤的用戶任務(wù)中
<boundaryEvent attachedToRef="子流程id" cancelActivity="true">
<errorEventDefinition errorRef="errorEvent"></errorEventDefinition>
</boundaryEvent>
-
信號(hào)事件
(1)信號(hào)開始事件
信號(hào)開始流程
??編寫流程定義文件
<signal id="mySignal" name="signal_start"></signal>
<process id="my-process">
<startEvent id="start">
<signalEventDefinition signalRef="mySignal"></signalEventDefinition>
</startEvent>
<sequenceFlow id="flow1" sourceRef="start" targetRef="someTask"/>
<userTask id="someTask" name="用戶任務(wù)節(jié)點(diǎn)"/>
<sequenceFlow id="flow2" sourceRef="someTask" targetRef="end" />
<endEvent id="end" />
</process>
??編寫測(cè)試類發(fā)出信號(hào)盟萨,啟動(dòng)流程,最終程序會(huì)阻塞到 someTask節(jié)點(diǎn)上了讨。
@Test
@Deployment(resources = "my-process.bpmn20.xml")
public void test() throws InterruptedException {
RuntimeService runtimeService = activitiRule.getRuntimeService();
runtimeService.signalEventReceived("signal_start");
Task task = activitiRule.getTaskService().createTaskQuery().singleResult();
logger.info("當(dāng)前的節(jié)點(diǎn) task = {}", task.getName());
}
(2)信號(hào)中間事件
??消息中間事件的流程定義節(jié)點(diǎn)中會(huì)包括兩種節(jié)點(diǎn)捻激,事件拋出節(jié)點(diǎn)和事件捕獲節(jié)點(diǎn)。
<signal id="mySignal" name="signal_start"></signal>
<process id="my-process">
<intermediateThrowEvent name="throwEvent">
<signalEventDefinition signalRef="mySignal"></signalEventDefinition>
</intermediateThrowEvent>
<intermediateCatchEvent>
<signalEventDefinition signalRef="mySignal"></signalEventDefinition>
</intermediateCatchEvent>
</process>
- 消息事件
??消息事件和信號(hào)事件類似前计,代碼就不在演示了胞谭。
<message id="pay" name="pay_message"></message>
<message id="generateOrder" name="gene_message"></message>
<process id="my-process">
<startEvent id="start">
<messageEventDefinition messageRef="pay"></messageEventDefinition>
</startEvent>
<intermediateCatchEvent id="order">
<messageEventDefinition messageRef="generateOrder"></messageEventDefinition>
</intermediateCatchEvent>
</process>