activiti学习(五)——执行监听器与任务监听器的基本使用

2023-11-08

本文介绍执行监听器与任务监听器的基本原理和使用方法。当流程途径连线或者节点的时候,会触发对应的事件类型。执行监听器与任务监听器在生产中经常会用在几个方面:

  • 动态分配节点处理人。通过前一个节点设置的变量,在运行到下一个节点时设置对应的处理人;
  • 当流程运行到某个节点时,发送邮件或短信给待办用户;
  • 统计流程处理时长,是否超时等;
  • 业务层面数据处理。

任务监听器顾名思义是监听任务的。任务监听器的生命周期如下图所示,会经历assignment、create、complete、delete。当流程引擎触发这四种事件类型时,对应的任务监听器会捕获其事件类型,再按照监听器的处理逻辑进行处理。

执行监听器则监听流程的所有节点和连线。主要有start、end、take事件。其中节点有start、end两种事件,而连线则有take事件。下图是执行监听器的生命周期:

接下来通过代码去演示监听器效果。 首先我们创建一个执行监听器的类:

package listener;

import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;

public class MyExecutionListener implements ExecutionListener {

	public void notify(DelegateExecution execution) throws Exception {
		System.out.println("============executionListener start============");
		String eventName = execution.getEventName();
		String currentActivitiId = execution.getCurrentActivityId();
		System.out.println("事件名称:" + eventName);
		System.out.println("ActivitiId:" + currentActivitiId);
		System.out.println("============executionListener  end============");
	}
}

自定义执行监听器需要实现ExecutionListener接口,并且实现notify方法。这里我们打印对应的事件和活动节点id

接下来创建一个自定任务监听器:

package listener;

import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;

public class MyTaskListener implements TaskListener{

	public void notify(DelegateTask delegateTask) {
		System.out.println("============TaskListener start============");
		String taskDefinitionKey = delegateTask.getTaskDefinitionKey();
		String eventName = delegateTask.getEventName();
		System.out.println("事件名称:" + eventName);
		System.out.println("taskDefinitionKey:" + taskDefinitionKey);
		System.out.println("============TaskListener end============");
	}
}

自定义任务监听器需要实现TaskListener接口,并且实现notify方法。这里我们打印对应的事件和任务节点键值(即bpmn图里userTask的id)。

之后新建一个bpmn图:

<?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/test">
  <process id="listenerBpmProcess" name="My process" isExecutable="true">
    <startEvent id="startevent1" name="Start"></startEvent>
    <userTask id="usertask1" name="myTask1" activiti:assignee="张三">
      <extensionElements>
        <activiti:executionListener event="start" class="listener.MyExecutionListener"></activiti:executionListener>
        <activiti:executionListener event="end" class="listener.MyExecutionListener"></activiti:executionListener>
        <activiti:taskListener event="all" class="listener.MyTaskListener"></activiti:taskListener>
      </extensionElements>
    </userTask>
    <endEvent id="endevent1" name="End"></endEvent>
    <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
    <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_listenerBpmProcess">
    <bpmndi:BPMNPlane bpmnElement="listenerBpmProcess" id="BPMNPlane_listenerBpmProcess">
      <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
        <omgdc:Bounds height="41.0" width="35.0" x="505.0" y="40.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
        <omgdc:Bounds height="55.0" width="105.0" x="470.0" y="150.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="505.0" y="240.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
        <omgdi:waypoint x="522.0" y="81.0"></omgdi:waypoint>
        <omgdi:waypoint x="522.0" y="150.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
        <omgdi:waypoint x="522.0" y="205.0"></omgdi:waypoint>
        <omgdi:waypoint x="522.0" y="240.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

这里我们给userTask1添加了执行监听器和任务监听器。部署bpmn图后,我们观察流程运转时监听器的触发时机和作用,启动流程:

public void startProcessById() {
    RuntimeService runtimeService = pe.getRuntimeService();
    ProcessInstance pi = runtimeService.startProcessInstanceById("listenerBpmProcess:1:4");
}

流程启动后,从开始节点运转到userTask1节点,观察控制台输出:

============executionListener start============
事件名称:start
ActivitiId:usertask1
============executionListener  end============
============TaskListener start============
事件名称:assignment
taskDefinitionKey:usertask1
============TaskListener end============
============TaskListener start============
事件名称:create
taskDefinitionKey:usertask1
============TaskListener end============

可以看到流程走到userTask1节点时,首先触发start事件,调用我们自定义的执行监听器,随后触发assignment和create事件,执行自定义任务监听器的内容。注意这里是先触发assignment进行人员分配,再触发create事件,与一般的认知有些差异。

接下来通过taskService的complete方法完成userTask1节点上流程的提交,观察控制台输出:

============TaskListener start============
事件名称:complete
taskDefinitionKey:usertask1
============TaskListener end============
============TaskListener start============
事件名称:delete
taskDefinitionKey:usertask1
============TaskListener end============
============executionListener start============
事件名称:end
ActivitiId:usertask1
============executionListener  end============

可以看到userTask1节点提交的时候,首先触发complete事件再触发delete事件,最后触发end事件。

以上就是执行监听器与任务监听器的基本使用方式。实际工程中,由于流程节点十分多,并且流程和业务常常需要进行微调,通常是不会在bpmn图上逐个节点添加监听器的,往往是在解析bpmn对象期间利用对象解析器动态添加监听器。这里涉及的原理比较复杂,留到后面的文章再讨论。

到本文为止,讲的都是activiti的入门用法,可以顺利跑通一个流程,还能在流程运行的途中进行一些监听和操作。activiti的入门概念不少,但使用并不复杂。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

activiti学习(五)——执行监听器与任务监听器的基本使用 的相关文章

  • Activiti之一:部署activiti-admin、activiti-app、activiti-rest

    文章目录 各组件版本下载部署将war包放入tomcat 访问 在网上查找activiti相关资料 xff0c 发现对于activiti rest的使用很少 xff0c 而官网对于api的支持还是比较多的 xff0c 如果考虑的是一个纯粹的工
  • activiti-serviceTask(服务任务)

    Activiti服务任务 serviceTask Activiti服务任务 serviceTask 作者 邓家海 都有一段沉默的时间 等待厚积薄发 应用场景 当客户有这么一个需求 下一个任务我需要自动执行一些操作 并且这个节点不需要任何的人
  • ACTIVITI 5.22.0 流程退回上一节点,实现多实例串行与并行退回

    import java util ArrayList import java util Date import java util HashSet import java util List import java util Map imp
  • 从Activiti切换到Camunda的5个理由

    原文 5 Reasons to switch from Activiti to Camunda 最近 Alfresco Activiti的前关键工程师宣布辞去Alfresco的职务 他们Fork了Activiti并开始了他们自己的项目 Fl
  • activiti学习之并行网关

    写在前面 并行网关用于处理流程并发的场景 可以将流程分发到多个执行流程 也可以让多个执行流程合并为一个执行流 但不是必须一起使用 也就是说并行网关有两种行为 分叉和合并 下面我们来一起看下 场景 学生请假同时由班长和班主任审批 等到班长和班
  • Spring Cloud 2.x之整合工作流Activiti

    工作流在项目中非常常用 这里先来看两张图 第一张 第二张 对以上两张图进行说明 假设这两张图就是华谊兄弟的请假流程图 图的组成部分 人物 范冰冰 冯小刚 王中军 事件 动作 请假 批准 不批准 工作流 Workflow 就是 业务过程的部分
  • activiti-Cancel activity属性(cancelActivity)作用

    流程设计工具 activiti explorer activiti版本 5 22 在使用边界计时器事件时 事件有一个参数 Cancel activity 作用上图 如下 Cancel activity选中 在事件中设置5秒计时 当开始流程后
  • Activiti7 监听器【十四】

    Activiti 7系列文章目录 文章代码下载 Activiti7 工作流设计器 一 Activiti7 创建表 二 Activiti7 表结构介绍 三 Activiti7 设计器创建流程 四 Activiti7 部署流程 五 Activi
  • Activiti和tk.mybatis的坑

    近期开发关于工作流的项目 遇到一个很坑的问题 activiti和tk mybatis居然会有冲突 先看异常 报错的原因大概就算这句话 Parameter 1 of method springProcessEngineConfiguratio
  • springboot整合activiti7

    一 添加依赖
  • 万字详解:Activiti 工作流引擎

    点击上方 芋道源码 选择 设为星标 管她前浪 还是后浪 能浪的浪 才是好浪 每天 10 33 更新文章 每天掉亿点点头发 源码精品专栏 原创 Java 2021 超神之路 很肝 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网
  • 2023最新版本Activiti7系列-源码篇-初始化过程

    源码分析 1 设计模式 1 1 命令模式 https dpb bobokaoya sm blog csdn net article details 89115420 1 2 责任链模式 https dpb bobokaoya sm blog
  • Activiti 架构分析

    Activiti是业界很流行的java工作流引擎 关于Activiti与JBPM5的关系和如何选择不是本文要讨论的话题 相关内容可以baidu一下 Activiti从架构角度看是比较优秀的 是很面向对象的 是我所阅读过的代码结构很棒的开源软
  • activiti5.17.0流程图及节点显示

    引用 activiti流程图上获取各节点的信息获取 这篇文章写得很好 揭示了图片点击出现信息的方法 于是我也做了 只不过有些改动 可能是activiti的版本不同的原因 jsp页面 通过流程实例id进行操作
  • activiti学习之服务任务

    写在前面 对于工作流 我们使用最多的是用户任务节点 用户任务节点就是给用户来生成任务的 需要人来手动的处理 而与之对应的还有服务任务节点 这种类型的节点需要人手动的参与而是程序来执行 即执行某个类的某个方法 这个类一般是org activi
  • (四)activiti7大服务service详解——2 RuntimeService

    前言 在 Activiti 中 每当一个流程定义被启动一次之后 都会生成一个相应的流程对象实例 Runtime Service 提供了启动流程 查询流程实例 设置获取流程实例变量等功能 此外它还提供了对流程部署 流程定义和流程实例的存取服务
  • Spring新事务与Retryable相结合

    如果我有一个方法 对于某个异常有 Spring 可重试 并且还有一个 Transactional Requires new 那么每次重试完成时 它会创建一个新事务还是使用现有事务 ie Retryable maxAttempts 5 bac
  • 如何将候选用户列表传递给 alfresco 中的 activiti 工作流任务?

    我希望能够传递作为任务候选者的用户列表 用户是从数据列表中检索的 不能作为一个组使用 Activiti candidateUsers 似乎是正确的方法 假设已获取用户并将其设置在变量 ipw reviwers 中
  • 开源 BPM 工具(如 Activiti、bonita)和 Windows Workflow Foundation 之间有什么区别

    我试图找到一个基于asp net的免费开源BPM工具 但不幸的是我没有找到这样的工具 但最近我读到一篇关于Windows Workflow Foundation的文章 那么它是否提供了类似于开源BPM工具如Activiti bonita J
  • 复杂的 Activiti + JPA 查询

    我们正在尝试在一个新项目中使用Activiti 我创建了一个设置 它通过 JPA 使用 Hibernate 来持久保存流程中涉及的实体 并且 JPA 与 Activiti 互连 因此我们可以将这些实体用作 JPA 变量 看 Activiti

随机推荐

  • 一维数组部分实验

    学习目标 1 理解数组的概念 掌握数组的定义及其存储结构 2 掌握一维数组的输入 输出及初始化的方法 3 掌握一维数组的使用 4 掌握与数组有关的算法 学习内容 1 编写程序 将10个整型数2 4 6 18 20赋予一个数组 然后输出该数组
  • 【C语言】初识指针

    C语言 初识指针 一 指针是什么 二 指针和指针类型 1 指针 整数 2 指针的解引用 三 野指针 1 野指针成因 2 如何规避野指针 四 指针运算 五 二级指针 七 指针数组 个人主页 库库的里昂 CSDN新晋作者 欢迎 点赞 评论 收藏
  • c的按位取反运算符(~) 与逻辑逻辑(!)

    位运算 位运算的运算分量只能是整型或字符型数据 位运算把运算对象看作是由二进位组成的位串信息 按位完成指定的运算 得到位串信息的结果 位运算符有 按位与 按位或 按位异或 按位取反 其中 按位取反运算符是单目运算符 其余均为双目运算符 位运
  • ffmpeg 采集音频数据

    音视频数据采集的步骤 设备注册 设置对应的采集方式 avfoundation dshow alas 打开设备 具体的例子 include
  • 什么是导航与位置服务器,GPS导航和GPS定位仪与GPS定位器的区别在哪?

    也许很多人时常都能听到GPS定位器 GPS导航 GPS定位仪这三个词 但都不是很了解GPS定位器 GPS导航和GPS定位仪这三者间的区别 往往都很模糊 那么 这三者到底分别是什么设备 又有哪些我们不知道的区别呢 一 GPS导航 但凡是自己有
  • 学成在线笔记+踩坑(2)——【内容模块】课程基础查询,swagger+数据库字典+Httpclient+跨域

    导航 黑马Java笔记 踩坑汇总 JavaSE JavaWeb SSM SpringBoot 瑞吉外卖 SpringCloud 黑马旅游 谷粒商城 学成在线 牛客面试题 java黑马笔记 目录 1 内容模块 需求分析 2 内容模块 模块工程
  • jdbc链接mysql8的url

    jdbc链接mysql8的url 使用jar或者maven依赖不同 java与mysql8 0连接Jdbc驱动的配置参数 驱动 driver com mysql cj jdbc Driver 字符串 jdbc url jdbc mysql
  • redis 缓存击穿 看一篇成高手系列3

    什么是缓存击穿 在谈论缓存击穿之前 我们先来回忆下从缓存中加载数据的逻辑 如下图所示 因此 如果黑客每次故意查询一个在缓存内必然不存在的数据 导致每次请求都要去存储层去查询 这样缓存就失去了意义 如果在大流量下数据库可能挂掉 这就是缓存击穿
  • 自己实现c++ list模板类,亲测可用

    双向链表模板类 dlist h ifndef DLIST H define DLIST H include
  • 秋招-准备计划

    秋招 准备计划 基本信息 时间 9月 10月 岗位 java后端开发 目标 中厂 大厂 有高用户量的项目 企业优先 准备 简历 基本信息 获奖情况 项目经历 实习经历 笔试 算法与数据结构 面试 Java篇 基本知识 JVM JUC多线程
  • SQLserver分页 高效率

    SQL Server 存储过程的分页 这个问题已经讨论过几年了 很多朋友在问我 所以在此发表一下我的观点建立表 CREATE TABLE TestTable ID int IDENTITY 1 1 NOT NULL FirstName nv
  • 什么是云计算,云计算的基本原理是什么?

    云计算 cloudcomputing 分布式计算技术的一种 其最基本的概念 是透过网络将庞大的计算处理程序自动分拆成无数个较小的子程序 再交由多部服务器所组成的庞大系统经搜寻 计算分析之后将处理结果回传给用户 透过这项技术 网络服务提供者可
  • 在偏远乡村感受中国电信优厚服务

    春节期间 笔者在家使用中国电信天翼上网卡的过程中发现 目前中国电信的3G网络覆盖在偏远乡村还不是很到位 不过在3G市场的激烈竞争中 运营商的服务意识却有着明显的提升 笔者从北京回家过年 在江西南昌市的一家电信营业厅购买了3G上网卡 当时得知
  • Vue3引用Dplayer播放器播放m3u8,hls播放协议

    一 安装 npm安装Dplayer npm install S Dplayer yarn安装Dplayer yarn add Dplayer 播放协议为 hls 安装hls npm install hls js S 二 代码 我用的是vue
  • sed 命令的高级用法

    编辑命令 d 删除 p 显示模式空间的内容 a text 在行后面追加文本 支持使用 n实现多行追加 i text 在行前面插入文本 支持使用 n实现多行插入 c text 替换行为单行或多行文本 w path to somefile 保存
  • 查看服务器信息

    1 查看 CPU 物理个数 grep physical id proc cpuinfo sort u wc l 2 查看 CPU 核心数量 grep core id proc cpuinfo sort u wc l 3 查看 CPU 线程数
  • MATLAB教学_09影像处理二

    本文视频地址 https www bilibili com video av68228488 p 9 主要学习了初阶影像处理 有三个内容 图像阈值 背景预测 相关连的标签 计算米粒颗数 先将图片二值化 那么有米粒的区域应该是1 而没有的地方
  • [Leetcode] 19. 删除链表的倒数第N个节点

    题目描述 给定一个链表 删除链表的倒数第 n 个节点 并且返回链表的头结点 示例 给定一个链表 1 gt 2 gt 3 gt 4 gt 5 和 n 2 当删除了倒数第二个节点后 链表变为 1 gt 2 gt 3 gt 5 说明 给定的 n
  • 【满分】【华为OD机试真题2023B卷 JAVA&JS】计算误码率

    华为OD2023 B卷 机试题库全覆盖 刷题指南点这里 计算误码率 知识点双指针 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 误码率是最常用的数据通信传输质量指标 它可以理解为 在多少位数据中出现一位差错 移动通信网络中
  • activiti学习(五)——执行监听器与任务监听器的基本使用

    本文介绍执行监听器与任务监听器的基本原理和使用方法 当流程途径连线或者节点的时候 会触发对应的事件类型 执行监听器与任务监听器在生产中经常会用在几个方面 动态分配节点处理人 通过前一个节点设置的变量 在运行到下一个节点时设置对应的处理人 当