文章目录
- 一、执行监听器
- 事件类型
- 生命周期
- 配置方式(选)
- 代码实现
- xml文件
- 创建监听器
- class方法
- expression方法
- delegateExpression
- 测试流程
- 部署流程
- 启动流程
- 完成任务
一、执行监听器
在流程实例执行过程中触发某个事件时,Activiti提供的执行监听器可以捕获该事件并执行相应的外部的Java代码,或者对指定的表达式求值。
事件类型
- EVENTNAME_START(start):开始事件
- EVENTNAME_TASK(take):执行事件(只能在顺序流,指线,sequenceFlow)
- EVENTNAME_END(end):结束事件
生命周期
示例:开始 -> 节点1 -> 节点2 -> 结束
配置方式(选)
- class:直接配置class全名
- expression:spring bean容器对应名字与方法名
- delegateExpression:spring bean容器对应名字
代码实现
·
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/processdef"><process id="execution-listener" name="执行监听器" isExecutable="true"><documentation>测试执行监听器</documentation><startEvent id="sid-30244641-2a1c-43e5-af5b-e77db43488bf" name="开始"><documentation>开始了</documentation><extensionElements><activiti:executionListener class="com.lmw.test.activiti.listener.execution.MyExecutionListener1" event="start"><activiti:field name="expression1"><activiti:string><![CDATA[start-expression1]]></activiti:string></activiti:field><activiti:field name="expression2"><!-- activiti:expression从流程变量中获取值 --><activiti:expression><![CDATA[${expression2}]]></activiti:expression></activiti:field></activiti:executionListener><activiti:executionListener class="com.lmw.test.activiti.listener.execution.MyExecutionListener1" event="end"><activiti:field name="expression1"><activiti:string><![CDATA[end-expression1]]></activiti:string></activiti:field><activiti:field name="expression2"><activiti:string><![CDATA[end-expression2]]></activiti:string></activiti:field></activiti:executionListener></extensionElements></startEvent><userTask id="sid-9e62413f-e04f-4c81-8d0c-e73f17e125ec" name="节点1"><documentation>任务节点1</documentation><extensionElements><activiti:executionListener event="start" expression="${myExecutionListener2.notify(execution)}"/><activiti:executionListener event="end" expression="${myExecutionListener2.notify(execution)}"/></extensionElements></userTask><sequenceFlow id="sid-1af5e647-b03c-4b12-807d-4171dfdf7ae9" sourceRef="sid-30244641-2a1c-43e5-af5b-e77db43488bf" targetRef="sid-9e62413f-e04f-4c81-8d0c-e73f17e125ec" name="顺序流1"><documentation>顺序流1了</documentation><extensionElements><activiti:executionListener event="take" class="com.lmw.test.activiti.listener.execution.MyExecutionListener1"/></extensionElements></sequenceFlow><userTask id="sid-d903cb09-56c2-4cfe-bd05-5ba0699539d0" name="节点2"><documentation>任务节点2</documentation><extensionElements><activiti:executionListener event="start" delegateExpression="${myExecutionListener3}"/><activiti:executionListener event="end" delegateExpression="${myExecutionListener3}"/></extensionElements></userTask><sequenceFlow id="sid-300ac02e-dc56-4988-bdd4-fd94a5bb71f7" sourceRef="sid-9e62413f-e04f-4c81-8d0c-e73f17e125ec" targetRef="sid-d903cb09-56c2-4cfe-bd05-5ba0699539d0" name="顺序流2"><documentation>顺序流2了</documentation><extensionElements><activiti:executionListener event="take" expression="${myExecutionListener2.notify(execution)}"/></extensionElements></sequenceFlow><endEvent id="sid-ace3a923-023c-4226-875c-2a0a30cc1c50" name="结束"><documentation>结束了</documentation></endEvent><sequenceFlow id="sid-dbf73610-a8b4-4149-828e-4f5bc252c80d" sourceRef="sid-d903cb09-56c2-4cfe-bd05-5ba0699539d0" targetRef="sid-ace3a923-023c-4226-875c-2a0a30cc1c50" name="顺序流3"><documentation>顺序流3了</documentation><extensionElements><activiti:executionListener event="take" delegateExpression="${myExecutionListener3}"/></extensionElements></sequenceFlow></process><bpmndi:BPMNDiagram id="BPMNDiagram_execution-listener"><bpmndi:BPMNPlane bpmnElement="execution-listener" id="BPMNPlane_execution-listener"><bpmndi:BPMNShape id="shape-d4dd6424-1316-4c10-a8f9-f3c501cd4073" bpmnElement="sid-30244641-2a1c-43e5-af5b-e77db43488bf"><omgdc:Bounds x="-442.5" y="-6.75" width="30.0" height="30.0"/></bpmndi:BPMNShape><bpmndi:BPMNShape id="shape-bcd8743b-6857-42d1-bc71-bd3bb6eed795" bpmnElement="sid-9e62413f-e04f-4c81-8d0c-e73f17e125ec"><omgdc:Bounds x="-388.0" y="-31.75" width="100.0" height="80.0"/></bpmndi:BPMNShape><bpmndi:BPMNEdge id="edge-d562b253-050f-4617-bbad-2e16950c15e4" bpmnElement="sid-1af5e647-b03c-4b12-807d-4171dfdf7ae9"><omgdi:waypoint x="-412.5" y="8.25"/><omgdi:waypoint x="-388.0" y="8.25"/></bpmndi:BPMNEdge><bpmndi:BPMNShape id="shape-cd7c00d6-f5f0-4afe-867c-6f576efc286d" bpmnElement="sid-d903cb09-56c2-4cfe-bd05-5ba0699539d0"><omgdc:Bounds x="-259.0" y="-31.75" width="100.0" height="80.0"/></bpmndi:BPMNShape><bpmndi:BPMNEdge id="edge-44a5c4d2-2ab7-48f1-adc7-c7a7a099800c" bpmnElement="sid-300ac02e-dc56-4988-bdd4-fd94a5bb71f7"><omgdi:waypoint x="-288.0" y="8.25"/><omgdi:waypoint x="-259.0" y="8.25"/></bpmndi:BPMNEdge><bpmndi:BPMNShape id="shape-05cc9b19-8019-471d-b31c-bb41c42e3529" bpmnElement="sid-ace3a923-023c-4226-875c-2a0a30cc1c50"><omgdc:Bounds x="-123.0" y="-6.75" width="30.0" height="30.0"/></bpmndi:BPMNShape><bpmndi:BPMNEdge id="edge-923723d0-33e3-4a62-bed9-bb16d4c9b175" bpmnElement="sid-dbf73610-a8b4-4149-828e-4f5bc252c80d"><omgdi:waypoint x="-159.0" y="8.25"/><omgdi:waypoint x="-123.0" y="8.25"/></bpmndi:BPMNEdge></bpmndi:BPMNPlane></bpmndi:BPMNDiagram>
</definitions>
创建监听器
class方法
public class MyExecutionListener1 implements ExecutionListener {@Setterprivate Expression expression1;@Setterprivate Expression expression2;@Overridepublic void notify(DelegateExecution execution) {System.out.println("========================MyExecutionListener1========================");System.out.println("execution.getProcessInstanceId() = " + execution.getProcessInstanceId());System.out.println("execution.getEventName() = " + execution.getEventName());FlowElement currentFlowElement = execution.getCurrentFlowElement();System.out.println("currentFlowElement.getName() = " + currentFlowElement.getName());System.out.println("currentFlowElement.getDocumentation() = " + currentFlowElement.getDocumentation());System.out.println("currentFlowElement.getExecutionListeners() = " + currentFlowElement.getExecutionListeners());String currentActivityId = execution.getCurrentActivityId();System.out.println("currentActivityId = " + currentActivityId);Optional.ofNullable(expression1).ifPresent(item -> item.getValue(execution));Optional.ofNullable(expression2).ifPresent(item -> item.getValue(execution));}
}
expression方法
@Component
public class MyExecutionListener2 {public void notify(DelegateExecution execution) {System.out.println("========================MyExecutionListener2========================");System.out.println("execution.getProcessInstanceId() = " + execution.getProcessInstanceId());System.out.println("execution.getEventName() = " + execution.getEventName());FlowElement currentFlowElement = execution.getCurrentFlowElement();System.out.println("currentFlowElement.getName() = " + currentFlowElement.getName());System.out.println("currentFlowElement.getDocumentation() = " + currentFlowElement.getDocumentation());System.out.println("currentFlowElement.getExecutionListeners() = " + currentFlowElement.getExecutionListeners());String currentActivityId = execution.getCurrentActivityId();System.out.println("currentActivityId = " + currentActivityId);}
}
delegateExpression
@Component
public class MyExecutionListener3 implements ExecutionListener {@Overridepublic void notify(DelegateExecution execution) {System.out.println("========================MyExecutionListener3========================");System.out.println("execution.getProcessInstanceId() = " + execution.getProcessInstanceId());System.out.println("execution.getEventName() = " + execution.getEventName());FlowElement currentFlowElement = execution.getCurrentFlowElement();System.out.println("currentFlowElement.getName() = " + currentFlowElement.getName());System.out.println("currentFlowElement.getDocumentation() = " + currentFlowElement.getDocumentation());System.out.println("currentFlowElement.getExecutionListeners() = " + currentFlowElement.getExecutionListeners());String currentActivityId = execution.getCurrentActivityId();System.out.println("currentActivityId = " + currentActivityId);}
}
测试流程
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class TestActivityExecutionListener {@Autowiredprivate RepositoryService repositoryService;@Autowiredprivate RuntimeService runtimeService;@Autowiredprivate TaskService taskService;private static final String PROCESS_INSTANCE_ID = "5b10eb17-3b4d-11ee-982e-18c04dcd4aee";@Testpublic void deployProcess() throws IOException {ClassPathResource classPathResource = new ClassPathResource("/processes/execution-listener.bpmn20.xml");Deployment deploy = repositoryService.createDeployment().addInputStream(classPathResource.getPath(), classPathResource.getInputStream()).deploy();System.out.println("deploy = " + deploy);}@Testpublic void startProcess() {Map<String, Object> variables = new HashMap<>();variables.put("expression2", "start-expression2");String processDefinitionKey = "execution-listener";String businessKey = processDefinitionKey + ":" + "10001";ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, businessKey, variables);System.out.println("processInstance = " + processInstance);// 输出当前任务列表this.printTaskList(processInstance.getId());}@Testpublic void completeTask() {// 查询任务Task task = taskService.createTaskQuery().processInstanceId(PROCESS_INSTANCE_ID).singleResult();taskService.complete(task.getId());}private void printTaskList(String processInstanceId) {// 输出当前任务列表taskService.createTaskQuery().processInstanceId(processInstanceId).orderByTaskCreateTime().asc().list().forEach(k -> {System.out.println("===================任务列表===================");System.out.println("任务ID = " + k.getId());System.out.println("任务名称 = " + k.getName());System.out.println("任务负责人 = " + k.getAssignee());System.out.println("任务创建时间 = " + k.getCreateTime());System.out.println("===================身份列表===================");// 输出用户身份关系列表taskService.getIdentityLinksForTask(k.getId()).forEach(link -> {System.out.println("link.getType() = " + link.getType());System.out.println("link.getUserId() = " + link.getUserId());System.out.println("link.getGroupId() = " + link.getGroupId());System.out.println("link.getTaskId() = " + link.getTaskId());});});}}
部署流程
运行 deployProcess
启动流程
运行 startProcess,可以看到执行监听器的监听到的顺序,包括启动、顺序流、节点。
完成任务
运行 completeTask,首先完成的是任务节点1,可以看到end任务节点1 - take顺序流2 - start任务节点2
再次运行 completeTask,完成任务节点2,可以看到结束看整个执行流程。