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

文章目录

  • 一、执行监听器
    • 事件类型
    • 生命周期
    • 配置方式(选)
    • 代码实现
      • 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 {@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,可以看到结束看整个执行流程。
在这里插入图片描述

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

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

相关文章

(三十四)大数据实战——scala运行环境安装配置及IDEA开发工具集成

前言 本节内容我们主要介绍一下scala运行环境的安装配置以及在idea开发工具中集成scala插件&#xff0c;便于scala项目的开发。 在开始scala安装配置之前&#xff0c;我们要先安装好jvm运行环境&#xff0c;scala运行于Java虚拟机&#xff08;JVM&#xff09;上&#xff0c;并…

信息检索与数据挖掘|(四)索引构建

目录 &#x1f4da;硬件基础 &#x1f4da;基于块的排序索引方法 &#x1f407;BSBI算法(blocked sort-based indexing) &#x1f4da;内存式单遍扫描索引构建方法 &#x1f407;SPIMI算法(single-pass in-memory indexing) &#x1f4da;分布式索引构建方法 &#x1f4d…

自动化测试 —— Pytest fixture及conftest详解!

前言 fixture是在测试函数运行前后&#xff0c;由pytest执行的外壳函数。fixture中的代码可以定制&#xff0c;满足多变的测试需求&#xff0c;包括定义传入测试中的数据集、配置测试前系统的初始状态、为批量测试提供数据源等等。fixture是pytest的精髓所在&#xff0c;类似u…

科技资讯|苹果Vision Pro可通过手势ID检测不同用户

近日&#xff0c;美国专利局公布了苹果公司的一项专利申请&#xff0c;该专利申请涉及基于手部特征验证用户身份的技术。苹果指出&#xff0c;可能是多个家庭成员都想使用 Apple Vision Pro&#xff0c;系统必须识别不同的手势以控制 visionOS。在另一个示例中&#xff0c;苹果…

存储过程中双循环迭代数据

create or replace procedure pro_zszg_report6 is --让游标变量c_emps指向一个动态select查询的结果集 cursor c_report is select * from hbrmw6.rms_zszg_report ; --5G基站数 cursor c_report6 is select re.city_id,re.county_id,ce.relat…

从代码入手理解卡尔曼滤波器的原理之预测步骤(二)

// 预测步骤void predict() {// 对于 1D,没有控制输入,因此预测就是使用上一个状态的值。// 但不确定度会增加预测噪声P += Q;}在卡尔曼滤波器中,预测步骤是估算系统在下一个时间点的状态,同时更新状态估算的不确定性(方差)。让我们结合上述的室温测量例子来理解这个 pre…

qt软件崩溃的分析方法-定位源文件和行号

软件&#xff08;debug版exe或者release版exe&#xff09;在正常运行状态下&#xff08;不是gdb调试运行&#xff09;&#xff0c;如果软件崩掉&#xff0c;那么会直接闪退&#xff0c;软件什么也做不了&#xff0c;此时无法保存软件中的状态信息&#xff0c;此外&#xff0c;也…

基于变电站自动化系统中的安全措施分析及应用

摘要&#xff1a;阐述变电运行中的问题&#xff0c;电气自动化系统与安全运行措施&#xff0c;包括自动控制设备的投入&#xff0c;电气自动 化与计算机技术相、设备数据的采集与处理、自动化系统的升级、人工智能技术的应用。 关键词&#xff1a;自动控制&#xff1b;数据采…

【Redis】Redis持久化策略

目录 策略RDBbgsave执行流程RDB效果演示RDB优缺点 AOFAOF缓冲区刷新策略AOF的重写机制AOF重写机制的触发机制AOF重写流程 混合持久化同时存在aof和rdb快照&#xff0c;以谁为主&#xff1f;信号 策略 RDB > Redis DataBase 相当于定期的方式实现持久化AOF > Append Only…

用PHP爬取视频代码示例详细教程

以下是一个使用Symfony Panther和PHP进行爬虫的示例程序&#xff0c;用于爬虫企鹅上的视频。请注意&#xff0c;这个示例需要使用https://www.duoip.cn/get_proxy这段代码获取爬虫IP。 <?php // 引入所需的库 require vendor/autoload.php;use Symfony\Component\Panther\P…

人工智能应该怎么学?

人工智能这个词炙手可热&#xff0c;为了跟上时代的步伐&#xff0c;有许多小伙伴就想学习人工智能&#xff0c;今天来介绍一下人工智能究竟是什么&#xff1f;应该怎么学&#xff1f;怎么入门&#xff1f; 首先来看一下什么是人工智能&#xff1f; 人工智能 人工智能 人工智能…

部署ai画图服务器

我希望部署一套ai画图服务&#xff0c;比方说stablediffusion&#xff0c;来探讨ai与艺术的关系 当探讨AI与艺术的交汇时&#xff0c;我们不可避免地进入了一个新的创作时代&#xff0c;其中AI技术已经开始显著地影响和改变了传统的艺术创作方法。这个领域的新兴艺术家&#x…

Unity——数据存储的几种方式

一、PlayerPrefs PlayerPrefs适合用于存储简单的键值对数据 存储的数据会在游戏关闭后依然保持&#xff0c;并且可以在不同场景之间共享&#xff0c;适合用于需要在游戏不同场景之间传递和保持的数据。 它利用key-value的方式将数据保存到本地&#xff0c;跟字典类似。然后通…

Qt模态对话框与非模态对话框

本文介绍Qt模态对话框与非模态对话框。 1.模态对话框 模态对话框是指对话框弹出后&#xff0c;我们不能和其他对话框进行交互&#xff0c;阻塞在这里&#xff0c;直到关闭此对话框。 Qt中模态对话框编写&#xff1a; MyDialog dialog; int ret 0;ret dialog.exec(); if (…

ADAS可视化系统,让自动驾驶更简单 -- 入门篇

随着车载芯片的升级、技术的更新迭代&#xff0c;可视化ADAS逐渐变成汽车的标配走入大家的生活中&#xff0c;为大家的驾车出行带来切实的便捷。那么你了解HMI端ADAS的实现过程吗&#xff1f;作为ADAS可视化系统的入门篇&#xff0c;就跟大家聊一聊目前较常见的低消耗的一种ADA…

typora主题切换与推荐主题

在这篇博文中&#xff0c;我将向你展示如何给typora更换主题&#xff0c;并推荐几款出色的主题。通过这些主题的使用&#xff0c;你可以为你的typora编辑器增添一抹别样的风采&#xff0c;让你的写作体验更加美好、舒适。 typora替换主题的步骤非常简单&#xff0c;只需按照以…

C语言 形参、实参

定义 形参 形式上的参数&#xff0c;没有确定的值 实参 实际存在的&#xff0c;已经确定的参数&#xff0c;常量&#xff0c;变量&#xff0c;表达式&#xff0c;都是实参 区别 实参的值不随形参的变化而变化 在C语言中&#xff0c;数据传送是单向的&#xff0c;即只能把实…

MySQL的InnoDB存储引擎中的自适应哈希索引技术

一、自适应哈希索引的工作机制与优化策略 MySQL的InnoDB存储引擎使用了一种叫做自适应哈希索引&#xff08;Adaptive Hash Indexes&#xff09;的技术。在某些索引值被频繁访问的情况下&#xff0c;InnoDB会自动在内存中为这些值建立哈希索引&#xff0c;以加速查询操作。 何…

【Java 8的新特性】

引言 Java 8是Java编程语言的一个重要里程碑&#xff0c;它引入了许多令人兴奋的新特性和改进。这些新特性不仅使Java编程更加简洁和高效&#xff0c;还提供了更多的功能和灵活性。在本文中&#xff0c;我们将探讨Java 8的一些重要新特性&#xff0c;并展示它们是如何改变我们…

【日常业务开发】接口性能优化

【日常业务开发】接口性能优化 缓存本地缓存分布式缓存 数据库分库分表SQL 优化 业务程序并行化异步化池化技术预先计算事务粒度批量读写锁的粒度尽快return上下文传递空间换时间集合空间大小 缓存 本地缓存 本地缓存&#xff0c;最大的优点是应用和cache同一个进程内部&…