SpringBoot整合Activiti7——全局监听器(八)

文章目录

  • 一、全局监听器
    • 事件类型
    • 配置方式(选)
    • 日志监听器
    • 代码实现
      • xml文件
      • 创建全局监听器
      • 全局配置类
      • 测试流程
        • 部署流程
        • 启动流程


一、全局监听器

它是引擎范围的事件监听器,可以捕获所有的Activiti事件。

事件类型

ActivitiEventType 枚举类中包含全部事件类型

配置方式(选)

  1. spring bean配置

  2. 全局配置类设置(config.setEventListeners())

    config.setEventListeners(Collections.singletonList(new MyGlobalEventListener()));
    
  3. 启动流程动态添加并且可以指定要监听的事件类型(推荐)

    runtimeService.addEventListener(new MyGlobalEventListener(), ActivitiEventType.TASK_CREATED, ActivitiEventType.TASK_ASSIGNED, ActivitiEventType.TASK_COMPLETED);
    
  4. class

  5. expression

  6. delegateExpression

日志监听器

全局配置类开启:config.setEnableDatabaseEventLogging(true);

开启后可以在 act_evt_log表中看到相关的日志记录。

代码实现

在这里插入图片描述

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="global-listener" name="全局事件监听器" isExecutable="true"><documentation>测试全局事件监听器</documentation><extensionElements><!-- 需要高版本的插件才能不爆红 支持class expression delegateExpression 配置方式 -->
<!--      <activiti:eventListener entityType="task" delegateExpression="${myGlobalEventListener}"/>--></extensionElements><startEvent id="sid-30244641-2a1c-43e5-af5b-e77db43488bf" name="开始"><documentation>开始了</documentation></startEvent><userTask id="sid-9e62413f-e04f-4c81-8d0c-e73f17e125ec" name="节点1"activiti:assignee="${applyUserId}" activiti:candidateUsers="${candidateUsers}" activiti:candidateGroups="${candidateGroups}"><documentation>任务节点1</documentation></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></sequenceFlow><userTask id="sid-d903cb09-56c2-4cfe-bd05-5ba0699539d0" name="节点2"><documentation>任务节点2</documentation></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></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></sequenceFlow></process><bpmndi:BPMNDiagram id="BPMNDiagram_execution-listener"><bpmndi:BPMNPlane bpmnElement="global-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>

创建全局监听器

@Component("myGlobalEventListener")
public class MyGlobalEventListener implements ActivitiEventListener {@Overridepublic void onEvent(ActivitiEvent event) {System.out.println("========================MyGlobalEventListener========================");switch (event.getType()) {case TASK_CREATED:this.taskCreate(event);break;case TASK_ASSIGNED:this.taskAssigned(event);break;case TASK_COMPLETED:this.taskComplete(event);break;default:System.out.println("Event received: " + event.getType());}}/*** 上面的 onEvent 方法抛出异常的后续处理动作* false :表示忽略onEvent()方法方法中抛出的异常* true :表示onEvent()方法中抛出的异常继续向上传播,导致当前操作失败*/@Overridepublic boolean isFailOnException() {return false;}private void taskCreate(ActivitiEvent event) {System.out.println("===================任务创建事件===================");ActivitiEntityEventImpl activitiEntityEvent = (ActivitiEntityEventImpl) event;TaskEntity taskEntity = (TaskEntity) activitiEntityEvent.getEntity();System.out.println("taskEntity.getId() = " + taskEntity.getId());System.out.println("taskEntity.getName() = " + taskEntity.getName());System.out.println("taskEntity.getAssignee() = " + taskEntity.getAssignee());System.out.println("taskEntity.getIdentityLinks() = " + taskEntity.getIdentityLinks());System.out.println("taskEntity.getVariables() = " + taskEntity.getVariables());}private void taskAssigned(ActivitiEvent event) {System.out.println("===================任务分配事件===================");ActivitiEntityEventImpl activitiEntityEvent = (ActivitiEntityEventImpl) event;TaskEntity taskEntity = (TaskEntity) activitiEntityEvent.getEntity();System.out.println("taskEntity.getId() = " + taskEntity.getId());System.out.println("taskEntity.getName() = " + taskEntity.getName());System.out.println("taskEntity.getAssignee() = " + taskEntity.getAssignee());System.out.println("taskEntity.getIdentityLinks() = " + taskEntity.getIdentityLinks());System.out.println("taskEntity.getVariables() = " + taskEntity.getVariables());}private void taskComplete(ActivitiEvent event) {System.out.println("===================任务完成事件===================");ActivitiEntityEventImpl activitiEntityEvent = (ActivitiEntityEventImpl) event;TaskEntity taskEntity = (TaskEntity) activitiEntityEvent.getEntity();System.out.println("taskEntity.getId() = " + taskEntity.getId());System.out.println("taskEntity.getName() = " + taskEntity.getName());System.out.println("taskEntity.getAssignee() = " + taskEntity.getAssignee());System.out.println("taskEntity.getIdentityLinks() = " + taskEntity.getIdentityLinks());System.out.println("taskEntity.getVariables() = " + taskEntity.getVariables());}
}

全局配置类

@Configuration
public class Activiti7Config {@Autowiredprivate SpringProcessEngineConfiguration config;@PostConstructpublic void springProcessEngineConfiguration() {// 设置自定义的全局事件监听器,其他配置方式就不需要配置了。
//        config.setEventListeners(Collections.singletonList(new MyGlobalEventListener()));// 开启日志监听,开启后对性能有影响 act_evt_logconfig.setEnableDatabaseEventLogging(true);}
}

测试流程

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class TestActivityGlobalEventListener {@Autowiredprivate RepositoryService repositoryService;@Autowiredprivate RuntimeService runtimeService;@Autowiredprivate TaskService taskService;private static final String PROCESS_INSTANCE_ID = "728bb780-3be6-11ee-b0a5-18c04dcd4aee";@Testpublic void deployProcess() {Deployment deploy = repositoryService.createDeployment().addClasspathResource("processes/global-listener.bpmn20.xml").deploy();System.out.println("deploy = " + deploy);}@Testpublic void startProcess() {// 添加全局监听器runtimeService.addEventListener(new MyGlobalEventListener(), ActivitiEventType.TASK_CREATED, ActivitiEventType.TASK_ASSIGNED, ActivitiEventType.TASK_COMPLETED);Map<String, Object> variables = new HashMap<>();variables.put("applyUserId", "user123456");variables.put("candidateUsers", CollectionUtil.newArrayList("zhangsan", "lisi", "wangwu"));variables.put("candidateGroups", CollectionUtil.newArrayList("group1", "group2", "group3"));String processDefinitionKey = "global-listener";String businessKey = processDefinitionKey + ":" + "100002";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).taskAssignee("user123456").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,可以看到监听到任务节点1的创建和分配事件。
在这里插入图片描述

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

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

相关文章

跳跳狗小游戏

欢迎来到程序小院 跳跳狗 玩法&#xff1a;一直弹跳的狗狗&#xff0c;鼠标点击屏幕左右方向键进行弹跳&#xff0c;弹到不同物品会有不同的分数减扣&#xff0c;规定的时间3分钟内完成狗狗弹跳&#xff0c;快去跳跳狗吧^^。开始游戏https://www.ormcc.com/play/gameStart/198…

MySQL用户管理和授权

目录 一.用户管理 1.1.新建用户 1.2.查看用户 1.3.重命名用户rename 1.4.删除用户 1.5.修改当前登录用户密码 1.6.修改其他用户密码 1.7.忘记root 密码并找回 二.数据库用户授权 2.1.all privilege包含的权限 2.2.授予权限 ①允许指定用户查询指定数据库表 ②允许…

比较Excel中的两列目录编号是否一致

使用java代码比较excel中两列是否有包含关系&#xff0c;若有包含关系&#xff0c;核对编号是否一致。 excel数据样例如下&#xff1a; package com.itownet.hg;import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook;import j…

sqlsugar查询数据库下的所有表,批量修改表名字

查询数据库中的所有表 using SqlSugar;namespace 批量修改数据库表名 {internal class Program{static void Main(string[] args){SqlSugarClient sqlSugarClient new SqlSugarClient(new ConnectionConfig(){ConnectionString "Data Source(localdb)\\MSSQLLocalDB;In…

双热点机制结合。5+铜死亡+铁死亡相关基因生信思路

今天给同学们分享一篇结合铜死亡和铁死亡相关基因预测肿瘤预后、免疫和药敏的生信文章“A novel signature of combing cuproptosis- with ferroptosis-related genes for prediction of prognosis, immunologic therapy responses and drug sensitivity in hepatocellular car…

Jenkins自动化部署相关shell命令

1. 只后台启动&#xff1a; nohup java -jar jar/demo*.jar & 2. 增加命令启动日志输出位置&#xff0c;防止超时处理配置&#xff1a; nohup java -jar /soft/gitee-demo-0.0.1-SNAPSHOT.jar >mylog.log 2>&1 & 简化写法&#xff1a; nohup java -jar /s…

基于STM32F412RET6的智能桶硬件设计

一、智能桶功能需求&#xff1a; 智能桶是一直采用Cortex-M4 嵌入式平台&#xff0c;搭载NB-IotTO通讯模组、智能称重采集、智能门锁监控以及温度监测等装置。主要功能如下&#xff1a; ▲ 具有GPS定位功能&#xff0c;可以通过后台APP实时定位智能桶的位置。 ▲ 具有温度监测功…

【设计模式】第11节:结构型模式之“装饰器模式”

一、简介 装饰器模式主要解决继承关系过于复杂的问题&#xff0c;通过组合来替代继承。它主要的作用是给原始类添加增强功能。这也是判断是否该用装饰器模式的一个重要的依据。除此之外&#xff0c;装饰器模式还有一个特点&#xff0c;那就是可以对原始类嵌套使用多个装饰器。…

第5天:基础入门-资产架构amp;端口amp;应用amp;CDNamp;WAFamp;站库分离amp;负载均衡

第5天&#xff1a;基础入门-资产架构&端口&应用&CDN&WAF&站库分离&负载均衡 #知识点&#xff1a;1. 资产架构-端口&目录&插件接口&多站点&多应用 2. 番外安全-域名&服务器本身&服务厂商&管理人员 3. 考虑阻碍-站库分离&am…

Redis-使用java代码操作Redis

&#x1f3c5;我是默&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; ​ &#x1f31f;在这里&#xff0c;我要推荐给大家我的专栏《Linux》。&#x1f3af;&#x1f3af; &#x1f680;无论你是编程小白&#xff0c;还是有一定基础的程序员&#xff0c;这…

go语言 | grpc原理介绍(一)

参考 https://www.nowcoder.com/discuss/389810396381683712?sourceSSRsearch 这里是b站对应的csdn博客&#xff0c;比较详细的介绍grpc相关原理说明&#xff0c;首先是大概的一个流程图说明。 什么是 RPC &#xff1f; 远程过程调用&#xff08;RPC&#xff09;是计算机科…

[推荐]SpringBoot java实现文件/附件上传下载 服务器 数据库 拿来就用,简单实用

推荐一个思路非常简单又很实用的文件上传下载方式&#xff0c;代码十分简练&#xff0c;可以开箱即用&#xff0c;下面是使用到的一些工具类和业务代码&#xff1b; 1.文件上传实现 判断文件类型的工具类&#xff0c;一些使用到的实体类我会凡在文末&#xff0c;需要可以的自…

吴恩达《机器学习》4-1->4-5:多变量线性回归

一、引入多维特征 在多维特征中&#xff0c;我们考虑的不再是单一的特征&#xff0c;而是一组特征&#xff0c;例如房价模型中可能包括房间数、楼层等多个特征。这些特征将组成一个向量&#xff0c;表示为(&#x1d465;₁, &#x1d465;₂, . . . , &#x1d465;ₙ)&#x…

nodelist 与 HTMLCollection 的区别

原地址 https://cloud.tencent.com/developer/article/2013289 节点与元素 根据 W3C 的 HTML DOM 标准&#xff0c;HTML 文档中的所有内容都是节点&#xff1a; 整个文档是一个文档节点每个 HTML 元素是元素节点HTML 元素内的文本是文本节点每个 HTML 属性是属性节点注释是注…

ts 简易封装 axios,统一 API

文章目录 为什么要封装目标文件结构封装通用请求方法获得类型提示http 方法文件上传使用示例实例化post 请求类型提示文件上传 总结完整代码&#xff1a; 为什么要封装 axios 本身已经很好用了&#xff0c;看似多次一举的封装则是为了让 axios 与项目解耦。比如想要将网络请求…

视频增强和修复工具 Topaz Video AI mac中文版功能

Topaz Video AI mac是一款使用人工智能技术对视频进行增强和修复的软件。它可以自动降噪、去除锐化、减少压缩失真、提高清晰度等等。Topaz Video AI可以处理各种类型的视频&#xff0c;包括低分辨率视频、老旧影片、手机录制的视频等。 使用Topaz Video AI非常简单&#xff0c…

突破防火墙的一种方法

当Linux防火墙阻止来自某个ip的数据时&#xff0c;它应该是根据ip数据报里“源IP地址”字段取得的对方ip吧&#xff0c;那对方就不能通过篡改“源IP地址”来绕过防火墙吗&#xff1f;NAT模式下的路由器就修改了这个字段。 但这样的话&#xff0c;攻击者是收不到服务器返回的数…

学 Java 怎么进外企?

作者&#xff1a;**苍何&#xff0c;CSDN 2023 年 实力新星&#xff0c;前大厂高级 Java 工程师&#xff0c;阿里云专家博主&#xff0c;土木转码&#xff0c;现任部门技术 leader&#xff0c;专注于互联网技术分享&#xff0c;职场经验分享。 &#x1f525;热门文章推荐&#…

麒麟KYLINIOS软件仓库搭建01-新创建软件仓库服务器

原文链接&#xff1a;麒麟KYLINIOS软件仓库搭建01-新创建软件仓库服务器 hello&#xff0c;大家好啊&#xff0c;今天给大家带来麒麟桌面操作系统软件仓库搭建的文章01-新创建软件仓库服务器&#xff0c;本篇文章主要给大家介绍了如何在麒麟桌面操作系统2203-x86版本上搭建内网…

docker 下安装mysql8.0

在docker中查询mysql镜像 PS C:\Users\admin> docker search mysql NAME DESCRIPTION STARS OFFICIAL AUTOMATED mysql MySQL is a widely used, open-source relation……