flowable流程结束触发监听器 flowable获取结束节点 flowable流程结束事件响应监听器
flowable流程结束触发监听器 | flowable流程结束获取结束节点 | flowable流程结束事件响应监听器
下面代码是该监听器是对每个到达结束事件后执行的。
原本的流程定义是如果其中任意某个节点进行了驳回,则直接结束流程。
所以在每个节点的驳回对应的排他网关都设置了EndEvent
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.EndEvent;
import org.flowable.bpmn.model.FlowNode;
import org.flowable.common.engine.api.delegate.event.FlowableEvent;
import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.delegate.event.impl.FlowableEntityEventImpl;
import org.flowable.engine.impl.util.ProcessDefinitionUtil;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.stereotype.Component;import java.util.List;/*** @description 全局监听器,判断流程是不是运行到了最后一个EndEvent* @since 2024/1/15*/
@Slf4j
@Component
public class ProcessEndListener implements FlowableEventListener {@Overridepublic void onEvent(FlowableEvent event) {log.info("ProcessEndListener:{}", JSON.toJSONString(event.getType()));TaskService taskService = SpringUtil.getBean(TaskService.class);RuntimeService runtimeService = SpringUtil.getBean(RuntimeService.class);FlowableEntityEventImpl flowableEntityEvent = ((FlowableEntityEventImpl) event);ProcessInstance pi = (ProcessInstance) flowableEntityEvent.getEntity();List<Task> tasks = taskService.createTaskQuery().active().processInstanceId(pi.getId()).list();Task t = tasks.get(0);String bizKey = pi.getBusinessKey();log.info("ProcessEndListener#bizKey:{}", bizKey);String procDefId = pi.getProcessDefinitionId();List<Execution> exes = runtimeService.createExecutionQuery().processInstanceId(pi.getProcessInstanceId()).processDefinitionId(procDefId).executionId(t.getExecutionId()).list();String curActId = exes.get(0).getActivityId();//获得当前执行器的活动IDBpmnModel bm = ProcessDefinitionUtil.getBpmnModel(t.getProcessDefinitionId());FlowNode flowNode = (FlowNode) bm.getFlowElement(curActId);//获得当前节点if (flowNode instanceof EndEvent) {//判断当前节点是否为结束事件if (flowNode.getId().equals("end")) {//end是自定义的EndEvent节点的ID//todo 通知回调log.info("当前节点是结束节点:{}!!", JSON.toJSONString(flowNode));}}}@Overridepublic boolean isFailOnException() {return false;}@Overridepublic boolean isFireOnTransactionLifecycleEvent() {return false;}@Overridepublic String getOnTransaction() {return null;}}
百度关于该问题答案出来的几乎清一色全是同一个答案,给了三种方法,但是每个方法的代码都有他自定义的部分,是不完整的东西。
下面是网上找的东西,里面的flowableService是这个比玩意自定义的。
下面这段代码是被转载多次的代码, 它监听的是指向结束事件的上一个节点。
也就是他的当前节点可能是最后一岗。
然后最后一岗—>EndEvent
@Component
public class ProcessEndListener implements FlowableEventListener {@AutowiredFlowableService flowableService;@Overridepublic void onEvent(FlowableEvent event) {// 当前节点任务实体,TaskEntity taskEntity = (TaskEntity) ((FlowableEntityEventImpl) event).getEntity();String taskId = taskEntity.getId();String curActId = flowableService.getNodeId(taskId);String procDefId = ProcUtils.getProcessDefinitionByTaskId(taskEntity.getId()).getId();Process process = ProcessDefinitionUtil.getProcess(procDefId);//遍历整个process,找到endEventId是什么,与当前taskId作对比List<FlowElement> flowElements = (List<FlowElement>) process.getFlowElements();for (FlowElement flowElement : flowElements) {if (flowElement instanceof SequenceFlow) {SequenceFlow flow = (SequenceFlow) flowElement;FlowElement sourceFlowElement = flow.getSourceFlowElement();FlowElement targetFlowElement = flow.getTargetFlowElement();//如果当前边的下一个节点是endEvent,那么获取当前边if(targetFlowElement instanceof EndEvent && sourceFlowElement.getId().equals(curActId)){System.out.println("下一个是结束节点!!");}}}}@Overridepublic boolean isFailOnException() {return false;}@Overridepublic boolean isFireOnTransactionLifecycleEvent() {return false;}@Overridepublic String getOnTransaction() {return null;}
}
用我上面的代码实现示例这个b的代码
@Overridepublic void onEvent(FlowableEvent event) {log.info("ProcessEndListener:{}", JSON.toJSONString(event.getType()));TaskService taskService = SpringUtil.getBean(TaskService.class);RuntimeService runtimeService = SpringUtil.getBean(RuntimeService.class);FlowableEntityEventImpl flowableEntityEvent = ((FlowableEntityEventImpl) event);ProcessInstance pi = (ProcessInstance) flowableEntityEvent.getEntity();List<Task> tasks = taskService.createTaskQuery().active().processInstanceId(pi.getId()).list();Task t = tasks.get(0);String bizKey = pi.getBusinessKey();log.info("ProcessEndListener#bizKey:{}", bizKey);String procDefId = pi.getProcessDefinitionId();List<Execution> exes = runtimeService.createExecutionQuery().processInstanceId(pi.getProcessInstanceId()).processDefinitionId(procDefId).executionId(t.getExecutionId()).list();String curActId = exes.get(0).getActivityId();BpmnModel bm = ProcessDefinitionUtil.getBpmnModel(t.getProcessDefinitionId());FlowNode flowNode = (FlowNode) bm.getFlowElement(curActId);//如果当前节点是最后一岗List<SequenceFlow> outFlows = flowNode.getOutgoingFlows(); //此处需要获取他的下一个节点是否为EndEventfor (SequenceFlow sequenceFlow : outFlows) { //遍历outFlowssequenceFlow.getTargetFlowElement();//用该flow节点与EndEvent进行对比判断,也就是当前节点的下一个节点和EndEvent判断是否一致,是则说明当前节点就是最后一岗,且它的下一个节点就是结束事件}}
相关文章:
flowable流程结束触发监听器 flowable获取结束节点 flowable流程结束事件响应监听器
flowable流程结束触发监听器 | flowable流程结束获取结束节点 | flowable流程结束事件响应监听器 下面代码是该监听器是对每个到达结束事件后执行的。 原本的流程定义是如果其中任意某个节点进行了驳回,则直接结束流程。 所以在每个节点的驳回对应的排他网关都设…...
【Python3】【力扣题】389. 找不同
【力扣题】题目描述: 【Python3】代码: 1、解题思路:使用计数器分别统计字符串中的元素和出现次数,两个计数器相减,结果就是新添加的元素。 知识点:collections.Counter(...):字典子类&#x…...
【从0上手cornerstone3D】如何加载nifti格式的文件
在线演示 支持加载的文件格式 .nii .nii.gz 代码实现 npm install cornerstonejs/nifti-volume-loader// ------------- 核心代码 Start------------------- // 注册一个nifti格式的加载器 volumeLoader.registerVolumeLoader("nifti",cornerstoneNiftiImageVolu…...
c# 学习笔记 - 异步编程
文章目录 1. 异步编程介绍1.1 简单介绍1.2 async/await 使用1.3 Task/Task<TResult> 对象 2. 样例2.1 迅速启动所有任务,仅当需要结果才等待任务执行2.2 使用 await 调用异步方法,即使这个异步方法内有 await 也不会同时执行回调和向下执行操作(必…...
设置了uni.chooseLocation,小程序中打不开
设置了uni.chooseLocation,在小程序打不开,点击没反应,地图显现不出来; 解决方案: 1.Hbuilder——微信开发者工具路径没有配置 打开工具——>设置 2.微信小程序服务端口没有开 解决方法:打开微信开发…...
spring retry 配置及使用
spring retry 配置及使用 接口或功能因外界异常导致失败后进行重推机制 依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.1.RELEASE</version></p…...
uni-app的组件(二)
多项选择器checkbox-group 多项选择器,内部由多个 checkbox 组成。 <checkbox-group><checkbox checked color"red" value"1"></checkbox> 篮球<!-- disabled:是否禁用 --><checkbox disabled color"rgba(0,0…...
项目开发中安全问题以及解决办法——客户传进来的数据不可信
用户传进来的数据是不可信的,比如下面这种情况下: PostMapping("/order") public void wrong(RequestBody Order order) { this.createOrder(order); } Data public class Order { private long itemId; //商品ID private BigDecimal ite…...
解决springboot启动报Failed to start bean ‘subProtocolWebSocketHandler‘;
解决springboot启动报 Failed to start bean subProtocolWebSocketHandler; nested exception is java.lang.IllegalArgumentException: No handlers 问题发现问题解决 问题发现 使用springboot整合websocket,启动时报错,示例代码: EnableW…...
什么是技术架构?架构和框架之间的区别是什么?怎样去做好架构设计?(一)
什么是技术架构?架构和框架之间的区别是什么?怎样去做好架构设计?(一)。 在软件行业,对于什么是架构,都有很多的争论,每个人都有自己的理解。在不同的书籍上, 不同的作者, 对于架构的定义也不统一, 角度不同, 定义不同。 一、架构是什么 Linux 有架构,MySQL 有架构,J…...
【多线程】认识Thread类及其常用方法
📄前言: 本文是对以往多线程学习中 Thread类 的介绍,以及对其中的部分细节问题进行总结。 文章目录 一. 线程的 创建和启动🍆1. 通过继承 Thread 类创建线程🍅2. 通过实现 Runnable 接口创建线程🥦3. 其他方…...
多用户商业版 whisper 2.1在线搭建教程
1. 准备工作 购买许可证:确保你已经购买了足够数量的用户许可证,以便所有员工或客户都能使用软件。系统要求:检查你的服务器和客户端计算机是否满足软件的最低系统要求。网络配置:确保你的网络环境(如防火墙、路由器等…...
HEXO搭建个人博客
Hexo是一款基于Node.js的静态博客框架,可以生成静态网页托管在GitHub上。中文文档见HEXO 配置环境 安装Git:下载并安装Git 检查git是否正确安装: git --version 安装Node.js:Node.js 为大多数平台提供了官方的安装程序。注意安装…...
Spring MVC学习之——RequestMapping注解
RequestMapping注解 作用 用于建立请求URL和处理请求方法之间的对应关系。 属性 value:指定请求的实际地址,可以是一个字符串或者一个字符串列表。 value可以不写,直接在括号中写,默认就是value值 RequestMapping(value“/hel…...
鸿蒙原生应用/元服务开发-延迟任务开发实现(二)
一、接口说明 接口名接口描述startWork(work: WorkInfo): void;申请延迟任务stopWork(work: WorkInfo, needCancel?: boolean): void;取消延迟任务getWorkStatus(workId: number, callback: AsyncCallback>): void;获取延迟任务状态(Callback形式)g…...
机器学习在什么场景下最常用-九五小庞
机器学习在多个场景中都有广泛的应用,下面是一些常见的应用场景: 自然语言处理(NLP):如语音识别、自动翻译、情感分析、垃圾邮件过滤等。数据挖掘和分析:如市场分析、用户画像、推荐系统、欺诈检测等。智能…...
利用IP应用场景API识别真实用户
引言 在当今数字化时代,随着互联网的普及和应用的广泛,验证用户身份的重要性变得越来越突出。在许多场景中,特别是在涉及安全性、用户体验以及个人隐私保护方面,确定用户的真实身份至关重要。而IP应用场景API则是一种强大的工具&…...
Hugging Face怎么通过国内镜像去进行模型下载(hf-mirror.com)
一、引言 Hugging Face 🤗是一家专注于自然语言处理(NLP)技术的公司,以其开源贡献和先进的机器学习模型而闻名。该公司最著名的产品是 Transformers 库,这是一个广泛使用的 Python 库,它提供了大量预训练模…...
POKT Network 开启周期性通缩,该计划将持续至 2025 年
POKT Network(也被称为 Pocket Network)在通证经济模型上完成了重大的改进,不仅将通货膨胀率降至 5% 以下,并使 POKT 通证在 2025 年走向通缩的轨迹上,预计到2024 年年底通货膨胀率将降至 2% 以下。POKT Network 的 “…...
LRU Cache
文章目录 1. 什么是LRU Cache2. LRU Cache的实现3. LRU Cache的OJ题目分析AC代码 1. 什么是LRU Cache LRU是Least Recently Used的缩写,意思是最近最少使用,它是一种Cache替换算法。 什么是Cache? 狭义的Cache指的是位于CPU和主存间的快速RAM…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...
