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

news2024/12/27 13:16:23

文章目录

  • 一、执行监听器
    • 事件类型
    • 生命周期
    • 配置方式(选)
    • 代码实现
      • xml文件
      • 创建监听器
        • class方法
        • expression方法
        • delegateExpression
      • 测试流程
        • 部署流程
        • 启动流程
        • 完成任务


一、执行监听器

在流程实例执行过程中触发某个事件时,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文件

<?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 {

    @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));
    }
}
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 {

    @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);
    }
}

测试流程

@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());
            });
        });
    }

}
部署流程

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

启动流程

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

完成任务

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1100692.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI原生应用速通指南

作者 | 百度文库APP 导读 百度创始人、董事长兼首席执行官李彦宏早在今年年初所预测的&#xff1a;大模型时代最大的机会在于应用层&#xff0c;会出现“杀手级”应用。 全文4448字&#xff0c;预计阅读时间12分钟。 前言 “我们要让AI走下技术的“神坛”&#xff0c;深入应用的…

强化学习与视觉语言模型之间的碰撞,UC伯克利提出语言奖励调节LAMP框架

文章链接&#xff1a; https://arxiv.org/abs/2308.12270 代码仓库&#xff1a; https://github.com/ademiadeniji/lamp 在强化学习&#xff08;RL&#xff09;领域&#xff0c;一个重要的研究方向是如何巧妙的设计模型的奖励机制&#xff0c;传统的方式是设计手工奖励函数&…

微信小程序修改van-popup的背景颜色

效果图&#xff1a; van-popup背景颜色渐变 使用深度修改样式不生效&#xff0c;直接在 custom-style里面修改即可&#xff1b; <van-popup position"bottom"custom-style"height:25%;background:linear-gradient(95deg, #F8FCFF -0.03%, #EDF5FF 64.44…

JIRA 在 2024 年完全停止服务器版本支持

在服务器上的开源许可证版本已经要过期了&#xff0c;想去更新下。 发现&#xff0c;JIRA 的所有服务器版本的支持马上就要结束了。 这就意味着&#xff0c;如果你部署的服务器版本的 JIRA 的话&#xff0c;你将没有办法对服务器进行更新。 貌似&#xff0c;必须使用 JIRA 提供…

用建筑中智能消防应急照明系统的应用

【摘要】&#xff1a;火灾应急照明是火灾安全疏散、保障消防人员生命安全的关键。对电气设计人员来说&#xff0c;火灾紧急照明系统的设计非常必要&#xff0c;消防紧急照明系统启动与其正常工作状态有直接的关系&#xff0c;但由于其存在的问题通常不能被及时发现&#xff0c;…

苏轼的人生足迹

传说徐霞客游历了中国所有角落&#xff0c;但实际上北宋才子苏东坡也同样历经千辛万苦&#xff0c;漫游天涯海角。这两者的不同之处在于&#xff0c;徐霞客是为了旅游而旅游&#xff0c;而苏东坡的大部分旅程则是由于他的贬谪之事导致的。 苏东坡一生到过很多地方&#xff0c;…

如何打造智能公厕:实现智慧监测、自动化运营和智慧化管理

在现代城市里&#xff0c;公共厕所是人们不可或缺的基础设施之一。然而&#xff0c;传统的公厕管理方式已经无法满足人们对公厕的期望&#xff0c;因此需要采用智慧公厕管理系统来提升公厕服务的质量。本文将以智慧公厕领先厂家广州中期科技有限公司&#xff0c;大量精品案例现…

实验笔记之——可见光通信调制驱动芯片模组

本博文记录本团队研发出的VLC驱动调制芯片模组&#xff08;如下图所示&#xff09;的驱动调制代码烧录过程。 实物模组正面 实物模组反面 首先需要安装keil5&#xff0c;其安装与编译过程请参考博客&#xff1a;实验笔记之——单片机烧录的实验过程_烧录程序的基本步骤-CSDN博客…

ES6(ECMAScript 2015)有哪些新属性,如何判断当前浏览器是否支持?

ES6&#xff08;ECMAScript 2015&#xff09;引入了许多新的语法和特性&#xff0c;以增强 JavaScript 编程语言的功能。以下是一些常见的 ES6 语法和特性以及它们的解释&#xff1a; let 和 const 声明&#xff1a; let 和 const 用于声明变量&#xff0c;代替了旧的 var 关键…

什么是关系数据库,你知道吗?

什么是关系数据库管理系统 关系数据库管理系统&#xff08;RDBMS&#xff0c;relational database management system&#xff09;是基于关系数据模型的数字数据库&#xff0c;由 E. F. Codd 于 1970 年提出。 许多关系数据库都提供使用结构化查询语言 SQL&#xff08;Struct…

6、函数式编程--高级用法

目录 7. 高级用法基本数据类型优化并行流parallel()parallelStream() 7. 高级用法 基本数据类型优化 ​ 我们之前用到的很多Stream的方法由于都使用了泛型。所以涉及到的参数和返回值都是引用数据类型。 ​ 即使我们操作的是整数小数&#xff0c;但是实际用的都是他们的包装…

【触想智能】工业级触摸显示器的分类与应用分享

工业级触摸显示器是具有触摸功能的工业显示器&#xff0c;常见的触摸方式有电容触摸和电阻触摸。它是应用在工业上的设备&#xff0c;和普通的显示器有着很大的区别。 工业级触摸显示器由液晶触摸屏、功能主板、外壳三部分组成&#xff0c;结构用料一般都采用铝合金材质&#x…

企业现在开始准备应对2024技术趋势了

导读从完善和扩大人工智能的使用&#xff0c;到平衡创新需求与紧缩预算&#xff0c;企业需要了解多种新兴技术趋势。以下是将主导2024年的技术趋势&#xff0c;以及企业现在应该如何为此做好准备。 毫无疑问&#xff0c;2023年的主流技术趋势将集中在人工智能&#xff0c;更具…

Ubuntu 16.04 LTS third maintenance update release

Ubuntu 16.04 LTS (Xenial Xerus)今天迎来的第三个维护版本更新中&#xff0c;已经基于Linux Kernel 4.10内核&#xff0c;而且Mesa图形栈已经升级至17.0版本。Adam Conrad表示&#xff1a;“像此前LTS系列相似&#xff0c;16.04.3对那些使用更新硬件的用户带来了硬件优化。该版…

寻找可靠的软件外包开发公司

寻找可靠的软件外包开发公司是关键&#xff0c;以确保项目的顺利交付和质量。以下是一些方法和步骤&#xff0c;帮助您找到可靠的软件外包开发公司&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 明确…

众和策略:尾盘5分钟拉升意味着什么?

跟着投资者越来越重视股市改动&#xff0c;一些术语逐渐进入商场人员的词汇库中&#xff0c;例如“尾盘5分钟拉升”。这个概念在许多人眼中是听起来生疏的&#xff0c;但它实际上是股市生意中十分重要的一种现象。 简略来说&#xff0c;尾盘5分钟拉升是指股市在毕竟5分钟呈现了…

短视频剪辑矩阵系统开发解决的市场工具难点?

短视频剪辑矩阵系统开发源码----源头搭建 一、源码技术构建源码部署搭建交付之---- 1.需要协助系统完成部署、接口全部正常接入、系统正常运行多久&#xff1f;7个工作日 2.需要准备好服务器以及备案域名 3.短视频SEO模块一年项目带宽&#xff0c;带宽最低要求10M&#xff0c;…

解决笔记本无线网络5G比2.4还慢的奇怪问题

环境&#xff1a;笔记本Dell XPS15 9570&#xff0c;内置无线网卡Killer Wireless-n/a/ac 1535 Wireless Network Adapter&#xff0c;系统win10家庭版&#xff0c;路由器H3C Magic R2Pro千兆版 因为笔记本用的不多&#xff0c;一直没怎么注意网络速度&#xff0c;直到最近因为…

制作厂区电子地图所具备的必要条件分析

工业4.0时代的到来&#xff0c;使得制造业开始向智能化、网络化方向发展。随着科技的不断进步和数字化转型的加速&#xff0c;企业越来越需要利用先进的技术手段来提高运营效率。厂区电子地图能够更好地满足工厂智能化管理和运营的需求&#xff0c;促进数字化转型。那么如何制作…

2、Calcite 源码编译与运行

Calcite 源码编译与运行 一、概述 1&#xff09;简介 Calcite是一个数据库查询优化器。 2&#xff09;使用方式 1.将Calcite作为独立的服务&#xff0c;向下对接异构数据源&#xff0c;上层应用则使用Calcite原生的JDBC接口&#xff0c;利用SQL语句进行请求和响应。 2.将…