• SpringBoot整合Activiti7——执行监听器(六)



    一、执行监听器

    在流程实例执行过程中触发某个事件时,Activiti提供的执行监听器可以捕获该事件并执行相应的外部的Java代码,或者对指定的表达式求值。

    事件类型

    1. EVENTNAME_START(start):开始事件
    2. EVENTNAME_TASK(take):执行事件(只能在顺序流,指线,sequenceFlow)
    3. EVENTNAME_END(end):结束事件

    生命周期

    示例:开始 -> 节点1 -> 节点2 -> 结束

    在这里插入图片描述

    配置方式(选)

    1. class:直接配置class全名
    2. expression:spring bean容器对应名字与方法名
    3. delegateExpression:spring bean容器对应名字

    代码实现

    ·在这里插入图片描述

    xml文件

    
    <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>activiti:string>
              activiti:field>
              <activiti:field name="expression2">
                
                <activiti:expression>activiti:expression>
              activiti:field>
            activiti:executionListener>
            <activiti:executionListener class="com.lmw.test.activiti.listener.execution.MyExecutionListener1" event="end">
              <activiti:field name="expression1">
                <activiti:string>activiti:string>
              activiti:field>
              <activiti:field name="expression2">
                <activiti:string>activiti:string>
              activiti:field>
            activiti:executionListener>
          extensionElements>
        startEvent>
        <userTask id="sid-9e62413f-e04f-4c81-8d0c-e73f17e125ec" name="节点1">
          <documentation>任务节点1documentation>
          <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>任务节点2documentation>
          <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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91

    创建监听器

    class方法
    public class MyExecutionListener1 implements ExecutionListener {
    
        @Setter
        private Expression expression1;
        @Setter
        private Expression expression2;
    
        @Override
        public 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));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    delegateExpression
    @Component
    public class MyExecutionListener3 implements ExecutionListener {
    
        @Override
        public 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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    测试流程

    @RunWith(SpringRunner.class)
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
    public class TestActivityExecutionListener {
    
        @Autowired
        private RepositoryService repositoryService;
        @Autowired
        private RuntimeService runtimeService;
        @Autowired
        private TaskService taskService;
    
        private static final String PROCESS_INSTANCE_ID = "5b10eb17-3b4d-11ee-982e-18c04dcd4aee";
    
        @Test
        public 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);
        }
    
        @Test
        public 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());
        }
    
        @Test
        public 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());
                });
            });
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    部署流程

    运行 deployProcess
    在这里插入图片描述

    启动流程

    运行 startProcess,可以看到执行监听器的监听到的顺序,包括启动、顺序流、节点。
    在这里插入图片描述

    完成任务

    运行 completeTask,首先完成的是任务节点1,可以看到end任务节点1 - take顺序流2 - start任务节点2
    在这里插入图片描述
    再次运行 completeTask,完成任务节点2,可以看到结束看整个执行流程。
    在这里插入图片描述

  • 相关阅读:
    第6章 - 多无人车系统的协同控制 --> 多无人车系统建模
    SpringMVC枚举类型字段处理
    程序包lombok不存在,纠正网上错误答案
    云原生 | 企业内使用 CoreDNS 构建高性能、插件化的DNS服务器
    JWFD开源工作流-矩阵大模型的最新进展
    论文管理系统(准备工作)
    【锁相环系列4】QPSK调制信号的载波同步环结构比较和判决反馈环的MATLAB仿真
    python中的一个实用的库imghdr—用于探测图片格式
    c# sqlite 修改字段类型
    Golang命令行库
  • 原文地址:https://blog.csdn.net/weixin_51833408/article/details/132417347