EndEvent組件
EndEvent總述
EndEvent分爲四種,第一種爲普通EndEvent,第二種爲拋出錯誤的EndEvent,第三種爲終止流程的EndEvent,第四種爲取消流程的EndEvent【會觸發補償事件】下面開始逐一講解。
EndEvent(普通)
EndEvent是正常的結束事件聲明,EndEvent(普通)對應的XML內代碼如下:
<endEvent id="endevent1" name="End"></endEvent>
ErrorEndEvent(ErrorStartEvent+ErrorEndEvent)
ErrorEndEvent 可以拋出error用於被接收。執行帶有ErrorEndEvent的路線必定觸發error標識
【除ErrorEndEvent之外還有以下方式可以手動拋出error】
throw new org.activiti.engine.delegate.BpmnError(“對應的errorcode”);
流程圖總覽
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:xsd="http://www.w3.org/2001/XMLSchema" 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">
<error id="errortest" errorCode="errorCode"></error>
<process id="ErrorEnd" name="My process" isExecutable="true">
<startEvent id="startevent1" name="Start"></startEvent>
<endEvent id="errorendevent1" name="ErrorEnd">
<errorEventDefinition errorRef="errortest"></errorEventDefinition>
</endEvent>
<subProcess id="eventsubprocess1" name="Event sub Process" triggeredByEvent="true">
<startEvent id="errorstartevent1" name="Error start">
<errorEventDefinition errorRef="errortest"></errorEventDefinition>
</startEvent>
<endEvent id="endevent1" name="End"></endEvent>
<serviceTask id="servicetask2" name="Service Task" activiti:class="com.ptm.prdemo.servicetask.Through2"></serviceTask>
<sequenceFlow id="flow3" sourceRef="errorstartevent1" targetRef="servicetask2"></sequenceFlow>
<sequenceFlow id="flow4" sourceRef="servicetask2" targetRef="endevent1"></sequenceFlow>
</subProcess>
<serviceTask id="servicetask1" name="Service Task" activiti:class="com.ptm.prdemo.servicetask.Through"></serviceTask>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="servicetask1"></sequenceFlow>
<sequenceFlow id="flow2" sourceRef="servicetask1" targetRef="errorendevent1"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_ErrorEnd">
<bpmndi:BPMNPlane bpmnElement="ErrorEnd" id="BPMNPlane_ErrorEnd">
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
<omgdc:Bounds height="35.0" width="35.0" x="190.0" y="220.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="errorendevent1" id="BPMNShape_errorendevent1">
<omgdc:Bounds height="35.0" width="35.0" x="510.0" y="220.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="eventsubprocess1" id="BPMNShape_eventsubprocess1">
<omgdc:Bounds height="141.0" width="391.0" x="170.0" y="40.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="errorstartevent1" id="BPMNShape_errorstartevent1">
<omgdc:Bounds height="35.0" width="35.0" x="200.0" y="94.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="510.0" y="94.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="servicetask2" id="BPMNShape_servicetask2">
<omgdc:Bounds height="55.0" width="105.0" x="310.0" y="84.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="servicetask1" id="BPMNShape_servicetask1">
<omgdc:Bounds height="55.0" width="105.0" x="320.0" y="210.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="235.0" y="111.0"></omgdi:waypoint>
<omgdi:waypoint x="310.0" y="111.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
<omgdi:waypoint x="415.0" y="111.0"></omgdi:waypoint>
<omgdi:waypoint x="510.0" y="111.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="225.0" y="237.0"></omgdi:waypoint>
<omgdi:waypoint x="320.0" y="237.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="425.0" y="237.0"></omgdi:waypoint>
<omgdi:waypoint x="510.0" y="237.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
注意
Through
public class Through implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) {
System.out.println("執行了主流程的方法");
}
}
Through2
public class Through2 implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) {
System.out.println("執行了子流程的方法");
}
}
測試代碼
@Test
public void ErrorEnd(){
Deployment deployment = repositoryService.createDeployment()
.name("ErrorEnd")
.addClasspathResource("bpmn/ErrorEnd.bpmn")
.addClasspathResource("bpmn/ErrorEnd.png")
.deploy();
System.out.println("部署ID:"+deployment.getId());
System.out.println("部署名稱:"+deployment.getName());
runtimeService.startProcessInstanceByKey("ErrorEnd");
}
TerminateEndEvent
注意
終止事件事件表示爲結束事件,具有terminateEventDefinition子元素。terminateAll屬性是可選的,默認情況下爲false。可以添加可選屬性terminateAll。如果爲true,則無論在流程定義中是否放置終止結束事件,並且無論是否處於子流程(甚至是嵌套)、(根)流程實例都將終止。
<endEvent id="myEndEvent >
<terminateEventDefinition activiti:terminateAll="true"></terminateEventDefinition>
</endEvent>
流程圖總覽
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:xsd="http://www.w3.org/2001/XMLSchema" 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="TerminateEnd" name="My process" isExecutable="true">
<startEvent id="startevent1" name="Start"></startEvent>
<parallelGateway id="parallelgateway1" name="Parallel Gateway"></parallelGateway>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="parallelgateway1"></sequenceFlow>
<userTask id="usertask1" name="usertask1"></userTask>
<userTask id="usertask2" name="usertask2"></userTask>
<sequenceFlow id="flow2" sourceRef="parallelgateway1" targetRef="usertask1"></sequenceFlow>
<sequenceFlow id="flow3" sourceRef="parallelgateway1" targetRef="usertask2"></sequenceFlow>
<endEvent id="terminateendevent1" name="TerminateEndEvent">
<terminateEventDefinition></terminateEventDefinition>
</endEvent>
<sequenceFlow id="flow4" sourceRef="usertask1" targetRef="terminateendevent1"></sequenceFlow>
<endEvent id="endevent1" name="End"></endEvent>
<sequenceFlow id="flow5" sourceRef="usertask2" targetRef="endevent1"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_TerminateEnd">
<bpmndi:BPMNPlane bpmnElement="TerminateEnd" id="BPMNPlane_TerminateEnd">
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
<omgdc:Bounds height="35.0" width="35.0" x="110.0" y="200.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="parallelgateway1" id="BPMNShape_parallelgateway1">
<omgdc:Bounds height="40.0" width="40.0" x="240.0" y="197.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
<omgdc:Bounds height="55.0" width="105.0" x="380.0" y="130.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
<omgdc:Bounds height="55.0" width="105.0" x="380.0" y="260.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="terminateendevent1" id="BPMNShape_terminateendevent1">
<omgdc:Bounds height="35.0" width="35.0" x="610.0" y="140.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="620.0" y="270.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="145.0" y="217.0"></omgdi:waypoint>
<omgdi:waypoint x="240.0" y="217.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="260.0" y="197.0"></omgdi:waypoint>
<omgdi:waypoint x="260.0" y="157.0"></omgdi:waypoint>
<omgdi:waypoint x="380.0" y="157.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="260.0" y="237.0"></omgdi:waypoint>
<omgdi:waypoint x="260.0" y="287.0"></omgdi:waypoint>
<omgdi:waypoint x="380.0" y="287.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
<omgdi:waypoint x="485.0" y="157.0"></omgdi:waypoint>
<omgdi:waypoint x="610.0" y="157.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5">
<omgdi:waypoint x="485.0" y="287.0"></omgdi:waypoint>
<omgdi:waypoint x="620.0" y="287.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
這裏用來給下面獲取判斷是哪個usertask做標識
測試代碼
@Test
public void TerminateEnd(){
Deployment deployment = repositoryService.createDeployment()
.name("TerminateEnd")
.addClasspathResource("bpmn/TerminateEnd.bpmn")
.addClasspathResource("bpmn/TerminateEnd.png")
.deploy();
System.out.println("部署ID:"+deployment.getId());
System.out.println("部署名稱:"+deployment.getName());
ProcessInstance pi =runtimeService.startProcessInstanceByKey("TerminateEnd");
long exeCount = runtimeService.createExecutionQuery().processInstanceId(pi.getId()).count();
System.out.println("終止前執行流數量:" + exeCount);
Task task = taskService.createTaskQuery().processInstanceId(pi.getId()).taskName("usertask1").singleResult();
//Task task = taskService.createTaskQuery().processInstanceId(pi.getId()).taskName("usertask2").singleResult();
taskService.complete(task.getId());
exeCount = runtimeService.createExecutionQuery().processInstanceId(pi.getId()).count();
System.out.println("終止後執行流數量:" + exeCount);
ProcessInstance newPi = runtimeService.createProcessInstanceQuery().processInstanceId(pi.getId()).singleResult();
System.out.println(newPi);
}
備註
第一個task爲獲取執行終止事件之前的那個【上方的那個】usertask,註釋的是獲取下方那個usertask。
執行兩次用第一個usertask與第二個分別執行兩次,驗證普通結束事件與終止結束事件的不同。
【執行上方那個usertask,接着執行了終止結束事件。可以看到所有執行的任務全部被殺死】
【執行下方那個usertask,接着執行了普通結束事件。可以看到上發的流程任然存活】
CancelEndEvent
注意
取消結束事件只能與事務子流程結合使用【如下圖】。當到達取消結束事件時,拋出取消事件,必須由取消邊界事件捕獲。取消邊界事件然後取消交易並觸發補償。
取消結束事件表示爲結束事件,具有cancelEventDefinition子元素。
<endEvent id="myCancelEndEvent">
<cancelEventDefinition />
</endEvent>
補償處理服務設置
流程圖總覽【最基礎的取消結束事件demo】
全部採用servicetask方便獲取信息,也測試一下執行順序,綁定servicetask的三個類如下:
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:xsd="http://www.w3.org/2001/XMLSchema" 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="CancelEnd" name="My process" isExecutable="true">
<transaction id="transaction1" name="Transaction">
<endEvent id="cancelendevent1" name="CancelEnd">
<cancelEventDefinition></cancelEventDefinition>
</endEvent>
<startEvent id="startevent1" name="Start"></startEvent>
<serviceTask id="servicetask1" name="Process" activiti:class="com.ptm.prdemo.servicetask.Process"></serviceTask>
<sequenceFlow id="flow5" sourceRef="startevent1" targetRef="servicetask1"></sequenceFlow>
<sequenceFlow id="flow6" sourceRef="servicetask1" targetRef="cancelendevent1"></sequenceFlow>
<boundaryEvent id="boundarycompensation1" name="Compensate" attachedToRef="servicetask1" cancelActivity="true">
<compensateEventDefinition></compensateEventDefinition>
</boundaryEvent>
<serviceTask id="servicetask2" name="Compensate" isForCompensation="true" activiti:class="com.ptm.prdemo.servicetask.Compensate"></serviceTask>
<association id="association1" sourceRef="boundarycompensation1" targetRef="servicetask2"></association>
</transaction>
<startEvent id="startevent2" name="Start"></startEvent>
<sequenceFlow id="flow3" sourceRef="startevent2" targetRef="transaction1"></sequenceFlow>
<endEvent id="endevent1" name="End"></endEvent>
<sequenceFlow id="flow4" sourceRef="transaction1" targetRef="endevent1"></sequenceFlow>
<boundaryEvent id="boundarycancel1" name="Cancel" attachedToRef="transaction1" cancelActivity="true">
<cancelEventDefinition></cancelEventDefinition>
</boundaryEvent>
<serviceTask id="servicetask3" name="CancelEnd" activiti:class="com.ptm.prdemo.servicetask.CancelEnd"></serviceTask>
<sequenceFlow id="flow7" sourceRef="boundarycancel1" targetRef="servicetask3"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_CancelEnd">
<bpmndi:BPMNPlane bpmnElement="CancelEnd" id="BPMNPlane_CancelEnd">
<bpmndi:BPMNShape bpmnElement="transaction1" id="BPMNShape_transaction1">
<omgdc:Bounds height="221.0" width="391.0" x="250.0" y="120.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="cancelendevent1" id="BPMNShape_cancelendevent1">
<omgdc:Bounds height="35.0" width="35.0" x="560.0" y="180.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
<omgdc:Bounds height="35.0" width="35.0" x="290.0" y="180.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="servicetask1" id="BPMNShape_servicetask1">
<omgdc:Bounds height="55.0" width="105.0" x="390.0" y="170.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="boundarycompensation1" id="BPMNShape_boundarycompensation1">
<omgdc:Bounds height="30.0" width="30.0" x="430.0" y="210.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="servicetask2" id="BPMNShape_servicetask2">
<omgdc:Bounds height="55.0" width="105.0" x="494.0" y="260.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="boundarycancel1" id="BPMNShape_boundarycancel1">
<omgdc:Bounds height="30.0" width="30.0" x="440.0" y="330.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="startevent2" id="BPMNShape_startevent2">
<omgdc:Bounds height="35.0" width="35.0" x="90.0" y="213.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="760.0" y="213.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="servicetask3" id="BPMNShape_servicetask3">
<omgdc:Bounds height="55.0" width="105.0" x="540.0" y="380.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5">
<omgdi:waypoint x="325.0" y="197.0"></omgdi:waypoint>
<omgdi:waypoint x="390.0" y="197.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
<omgdi:waypoint x="495.0" y="197.0"></omgdi:waypoint>
<omgdi:waypoint x="560.0" y="197.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="association1" id="BPMNEdge_association1">
<omgdi:waypoint x="445.0" y="240.0"></omgdi:waypoint>
<omgdi:waypoint x="546.0" y="260.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="125.0" y="230.0"></omgdi:waypoint>
<omgdi:waypoint x="250.0" y="230.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
<omgdi:waypoint x="641.0" y="230.0"></omgdi:waypoint>
<omgdi:waypoint x="760.0" y="230.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7">
<omgdi:waypoint x="455.0" y="360.0"></omgdi:waypoint>
<omgdi:waypoint x="592.0" y="380.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
ServiceTask類
CancelEnd
public class CancelEnd implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) {
System.out.println("CancelEnd");
}
}
Compensate
public class Compensate implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) {
System.out.println("Compensate");
}
}
Compensate
public class Compensate implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) {
System.out.println("Compensate");
}
}
Process
public class Process implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) {
System.out.println("Process");
}
}
測試代碼
@Test
public void CancelEnd(){
Deployment deployment = repositoryService.createDeployment()
.name("CancelEnd")
.addClasspathResource("bpmn/CancelEnd.bpmn")
.addClasspathResource("bpmn/CancelEnd.png")
.deploy();
System.out.println("部署ID:"+deployment.getId());
System.out.println("部署名稱:"+deployment.getName());
runtimeService.startProcessInstanceByKey("CancelEnd");
}
順序無需記憶由裏到外依次執行
注意
邊界事件缺失程序執行會報錯