深圳做营销型网站/个人免费开发网站
写在前面
子流程作为主流程的一部分存在,拥有独立的开始节点和结束节点,即可以单独作为一个完整的流程来使用,当一个流程比较复杂时,可以考虑使用子流程来进行包裹,下面来一起看下。
1:测试
1.1:流程设计
- 效果图
- 说明
子流程使用了错误结束节点,错误结束节点也是一种结束节点,只不过我们使用最多的是普通的结束节点,结束时静默结束,而错误结束节点是在结束时会抛出一个错误编码,如下时我们设置的要抛出的错误编码:
然后在子流程边界定义了一个 错误边界事件 ,来捕获错误编码,让流程流转到主流程继续处理,如下是设置:
- 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="subProcessErrorEndEvent" name="subProcessErrorEndEvent" isExecutable="true"><startEvent id="startevent1" name="Start"></startEvent><subProcess id="subprocess1" name="Sub Process"><startEvent id="startevent2" name="Start"></startEvent><userTask id="usertask1" name="服务执行" activiti:assignee="subProcessUserName"></userTask><sequenceFlow id="flow2" sourceRef="startevent2" targetRef="usertask1"></sequenceFlow><exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway><endEvent id="endevent1" name="End"></endEvent><sequenceFlow id="flow3" sourceRef="exclusivegateway1" targetRef="endevent1"><conditionExpression xsi:type="tFormalExpression"><![CDATA[${flag == true}]]></conditionExpression></sequenceFlow><endEvent id="errorendevent1" name="ErrorEnd"><errorEventDefinition errorRef="error"></errorEventDefinition></endEvent><sequenceFlow id="flow4" sourceRef="exclusivegateway1" targetRef="errorendevent1"><conditionExpression xsi:type="tFormalExpression"><![CDATA[${flag == false}]]></conditionExpression></sequenceFlow><sequenceFlow id="flow5" sourceRef="usertask1" targetRef="exclusivegateway1"></sequenceFlow></subProcess><sequenceFlow id="flow1" sourceRef="startevent1" targetRef="subprocess1"></sequenceFlow><boundaryEvent id="boundaryerror1" name="Error" attachedToRef="subprocess1"><errorEventDefinition errorRef="error"></errorEventDefinition></boundaryEvent><userTask id="usertask2" name="错误任务" activiti:assignee="mainProcessErrorUserName"></userTask><sequenceFlow id="flow6" sourceRef="boundaryerror1" targetRef="usertask2"></sequenceFlow><endEvent id="endevent2" name="End"></endEvent><sequenceFlow id="flow7" sourceRef="usertask2" targetRef="endevent2"></sequenceFlow></process><bpmndi:BPMNDiagram id="BPMNDiagram_subProcessErrorEndEvent"><bpmndi:BPMNPlane bpmnElement="subProcessErrorEndEvent" id="BPMNPlane_subProcessErrorEndEvent"><bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1"><omgdc:Bounds height="35.0" width="35.0" x="170.0" y="250.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="subprocess1" id="BPMNShape_subprocess1"><omgdc:Bounds height="256.0" width="601.0" x="340.0" y="145.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="startevent2" id="BPMNShape_startevent2"><omgdc:Bounds height="35.0" width="35.0" x="380.0" y="241.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1"><omgdc:Bounds height="55.0" width="105.0" x="510.0" y="231.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1"><omgdc:Bounds height="40.0" width="40.0" x="680.0" y="238.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1"><omgdc:Bounds height="35.0" width="35.0" x="830.0" y="180.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="errorendevent1" id="BPMNShape_errorendevent1"><omgdc:Bounds height="35.0" width="35.0" x="830.0" y="290.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="boundaryerror1" id="BPMNShape_boundaryerror1"><omgdc:Bounds height="30.0" width="30.0" x="615.0" y="390.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2"><omgdc:Bounds height="55.0" width="105.0" x="577.0" y="520.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="endevent2" id="BPMNShape_endevent2"><omgdc:Bounds height="35.0" width="35.0" x="727.0" y="530.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2"><omgdi:waypoint x="415.0" y="258.0"></omgdi:waypoint><omgdi:waypoint x="510.0" y="258.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3"><omgdi:waypoint x="700.0" y="238.0"></omgdi:waypoint><omgdi:waypoint x="847.0" y="215.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4"><omgdi:waypoint x="700.0" y="278.0"></omgdi:waypoint><omgdi:waypoint x="847.0" y="290.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5"><omgdi:waypoint x="615.0" y="258.0"></omgdi:waypoint><omgdi:waypoint x="680.0" y="258.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1"><omgdi:waypoint x="205.0" y="267.0"></omgdi:waypoint><omgdi:waypoint x="340.0" y="273.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6"><omgdi:waypoint x="630.0" y="420.0"></omgdi:waypoint><omgdi:waypoint x="629.0" y="520.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7"><omgdi:waypoint x="682.0" y="547.0"></omgdi:waypoint><omgdi:waypoint x="727.0" y="547.0"></omgdi:waypoint></bpmndi:BPMNEdge></bpmndi:BPMNPlane></bpmndi:BPMNDiagram>
</definitions>
1.2:部署流程
@Test
public void deploy() {Deployment deployment = repositoryService.createDeployment() // 创建部署.addClasspathResource("com/jh/activiti/error_end_event.bpmn20.xml") // 加载流程资源文件.name("子流程中的错误结束节点测试") // 流程名称.deploy(); // 部署System.out.println("流程部署ID:" + deployment.getId());System.out.println("流程部署Name:" + deployment.getName());
}
1.3:启动流程实例
/*** 启动流程实例*/
@Test
public void start() throws InterruptedException {runtimeService.startProcessInstanceByKey("subProcessErrorEndEvent"); // 流程定义表的KEY字段值
}
此时生成子流程中服务执行
节点对应的任务,如下:
1.4:完成任务子流程正常结束
@Test
public void completeSubProcessNoError() {// 测试子流程不以错误节点结束,即不会执行到外部流程/*Map<String, Object> paramsMap = new HashMap<>();paramsMap.put("flag", true);taskService.complete("662510", paramsMap);*/// 测试子流程以错误节点结束,会执行到外部流程Map<String, Object> paramsMap = new HashMap<>();paramsMap.put("flag", true);taskService.complete("1075010", paramsMap); // 执行子流程任务节点
// taskService.complete("1070010"); // 被子流程的错误边界事件捕获,进入到外部任务阶段,完成外部任务节点
}
此时流程正常结束,不会流转到主流程:
1.5:完成任务子流程通过错误结束节点结束
@Test
public void completeSubProcessNoError() {// 测试子流程不以错误节点结束,即不会执行到外部流程/*Map<String, Object> paramsMap = new HashMap<>();paramsMap.put("flag", true);taskService.complete("662510", paramsMap);*/// 测试子流程以错误节点结束,会执行到外部流程Map<String, Object> paramsMap = new HashMap<>();paramsMap.put("flag", true);taskService.complete("1075010", paramsMap); // 执行子流程任务节点
// taskService.complete("1070010"); // 被子流程的错误边界事件捕获,进入到外部任务阶段,完成外部任务节点
}
执行后生成了外部的错误任务
节点对应的任务: