1. 任务监听器定义

任务监听器用于在特定的任务相关事件发生时,执行自定义的Java逻辑或表达式

2.监听器监听的事件

  1. String EVENTNAME_CREATE = "create";创建):当任务已经创建,并且所有任务参数都已经设置时触发
  2. String EVENTNAME_ASSIGNMENT = "assignment";(指派):当任务已经指派给某人时触发。请注意:当流程执行到达用户任务时,create事件触发前,首先触发assignment事件。这看起来不是自然顺序,但是有实际原因的:当收到create事件时,我们通常希望查看任务的所有参数,包括办理人。
  3. String EVENTNAME_COMPLETE = "complete"(完成):当任务已经完成,从运行时数据中删除前触发。
  4. String EVENTNAME_DELETE = "delete"(删除):在任务即将被删除前触发。请注意当任务通过completeTask正常完成时也会触发

注意:assignment事件比create先执行。

3. 任务监听实现方式——类class

实现接口org.activiti.engine.delegate.TaskListener

在流程定义文件中用class属性来指定该监听器

3.1 TaskListener源码

/*** @author Tom Baeyens*/
public interface TaskListener extends Serializable {//create(创建):当任务已经创建,并且所有任务参数都已经设置时触发String EVENTNAME_CREATE = "create";/**assignment(指派):当任务已经指派给某人时触发。请注意:当流程执行到达用户任务时,
create事件触发前,首先触发assignment事件。这看起来不是自然顺序,
但是有实际原因的:当收到create事件时,我们通常希望查看任务的所有参数,包括办理人。**/String EVENTNAME_ASSIGNMENT = "assignment";//(完成):当任务已经完成,从运行时数据中删除前触发String EVENTNAME_COMPLETE = "complete";//(删除):在任务即将被删除前触发。请注意当任务通过completeTask正常完成时也会触发String EVENTNAME_DELETE = "delete";/*** Not an actual event, used as a marker-value for {@link TaskListener}s that should be called for all events,* including {@link #EVENTNAME_CREATE}, {@link #EVENTNAME_ASSIGNMENT} and {@link #EVENTNAME_COMPLETE} and {@link #EVENTNAME_DELETE}.*/String EVENTNAME_ALL_EVENTS = "all";void notify(DelegateTask delegateTask);
}

xml文件中定义

<userTask id="usertask2" name="User Task" activiti:assignee="c"><extensionElements><activiti:taskListener event="all" class="com.daling.ch1.listener.MyExecutionListener"></activiti:taskListener></extensionElements>
</userTask>

3.2 类的定义

任务监听器中我们可以拿到DelegateTask对象,这个对象可以让我们操作activiti引擎中的一些东西,下面看一下DelegateTask类中的定义主要访法。

import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;/*** 任务监听器用于在特定的任务相关事件发生时,执行自定义的Java逻辑或表达式** 任务监听器支持下列属性:*  event(事件)(必填):任务监听器将被调用的任务事件类型。可用的事件有:*         create(创建):当任务已经创建,并且所有任务参数都已经设置时触发。*         assignment(指派):当任务已经指派给某人时触发。请注意:当流程执行到达用户任务时,create事件触发前,首先触发*         assignment事件。这看起来不是自然顺序,但是有实际原因的:当收到create事件时,我们通常希望查看任务的所有参数,包括*         办理人。*         complete(完成):当任务已经完成,从运行时数据中删除前触发。*         delete(删除):在任务即将被删除前触发。请注意当任务通过completeTask正常完成时也会触发**   class:需要调用的代理类。这个类必须实现 org.activiti.engine.delegate.TaskListener 接口***   expression:(不能与class属性一起使用):指定在事件发生时要执行的表达式。可以为被调用的对象传递 DelegateTask 对象与事件名(使用 task.eventName )作为参数****   delegateExpression:可以指定一个能够解析为 TaskListener 接口实现类对象的表达式。与服务任务类似***/
@Slf4j
public class SiteReportUserTask implements TaskListener {private static final long serialVersionUID = 3654543511891213996L;@Overridepublic void notify(DelegateTask delegateTask) {log.info("creattime: {}",delegateTask.getCreateTime());log.info("getProcessInstanceId: {}",delegateTask.getProcessInstanceId());log.info("数据库中的taskId主键: {}",delegateTask.getId());log.info("任务名称: {}",delegateTask.getName());delegateTask.setName("修改任务名称");log.info("获取任务的描述信息: {}",delegateTask.getDescription());delegateTask.setDescription("修改任务的描述信息");/*** lower priority: [0..19] lowest, [20..39] low, [40..59] normal, [60..79] high* [80..100] highest任务处理的优先级范围是0-100*/log.info("任务处理的优先级范围是0-100: {}",delegateTask.getPriority());delegateTask.setPriority(1); /** 修改优先级*/log.info("获取流程实例id: {}",delegateTask.getProcessInstanceId());log.info("获取流程获取执行id: {}",delegateTask.getExecutionId());log.info("获取流程定义id: {}",delegateTask.getProcessDefinitionId());/** 添一个加候选人 *///void addCandidateUser(String userId);/** 添加候选人集合 *///void addCandidateUsers(Collection<String> candidateUsers);/** 添加候选组 *///void addCandidateGroup(String groupId);String eventName = delegateTask.getEventName();if (EVENTNAME_CREATE.endsWith(eventName)) {System.out.println("create=========");}else if (EVENTNAME_ASSIGNMENT.endsWith(eventName)) {System.out.println("assignment========");}else if (EVENTNAME_COMPLETE.endsWith(eventName)) {System.out.println("complete===========");}else if (EVENTNAME_DELETE.endsWith(eventName)) {System.out.println("delete=============");}}
}

3.3 监听器委托类DelegateTask

/* Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at* *      http://www.apache.org/licenses/LICENSE-2.0* * Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/
package org.activiti.engine.delegate;import java.util.Collection;
import java.util.Date;
import java.util.Set;import org.activiti.engine.ActivitiObjectNotFoundException;
import org.activiti.engine.task.DelegationState;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.IdentityLinkType;/*** @author Joram Barrez*/
public interface DelegateTask extends VariableScope {/** DB id of the task. */String getId();/** Name or title of the task. */String getName();/** Change the name of the task. */void setName(String name);/** Free text description of the task. */String getDescription();/** Change the description of the task */void setDescription(String description);/** indication of how important/urgent this task is with a number between * 0 and 100 where higher values mean a higher priority and lower values mean * lower priority: [0..19] lowest, [20..39] low, [40..59] normal, [60..79] high * [80..100] highest */int getPriority();/** indication of how important/urgent this task is with a number between * 0 and 100 where higher values mean a higher priority and lower values mean * lower priority: [0..19] lowest, [20..39] low, [40..59] normal, [60..79] high * [80..100] highest */void setPriority(int priority);/** Reference to the process instance or null if it is not related to a process instance. */String getProcessInstanceId();/** Reference to the path of execution or null if it is not related to a process instance. */String getExecutionId();/** Reference to the process definition or null if it is not related to a process. */String getProcessDefinitionId();/** The date/time when this task was created */Date getCreateTime();/** The id of the activity in the process defining this task or null if this is not related to a process */String getTaskDefinitionKey();/** Indicated whether this task is suspended or not. */boolean isSuspended();/** The tenant identifier of this task */String getTenantId();/** The form key for the user task */String getFormKey();/** Change the form key of the task */void setFormKey(String formKey);/** Returns the execution currently at the task. */DelegateExecution getExecution();/** Returns the event name which triggered the task listener to fire for this task. */String getEventName();/** The current {@link org.activiti.engine.task.DelegationState} for this task. */DelegationState getDelegationState();/** Adds the given user as a candidate user to this task. */void addCandidateUser(String userId);/** Adds multiple users as candidate user to this task. */void addCandidateUsers(Collection<String> candidateUsers);/** Adds the given group as candidate group to this task */void addCandidateGroup(String groupId);/** Adds multiple groups as candidate group to this task. */void addCandidateGroups(Collection<String> candidateGroups);/** The {@link User.getId() userId} of the person responsible for this task. */String getOwner();/** The {@link User.getId() userId} of the person responsible for this task.*/void setOwner(String owner);/** The {@link User.getId() userId} of the person to which this task is delegated. */String getAssignee();/** The {@link User.getId() userId} of the person to which this task is delegated. */void setAssignee(String assignee);/** Due date of the task. */Date getDueDate();/** Change due date of the task. */void setDueDate(Date dueDate);/** The category of the task. This is an optional field and allows to 'tag' tasks as belonging to a certain category. */String getCategory();/** Change the category of the task. This is an optional field and allows to 'tag' tasks as belonging to a certain category. */void setCategory(String category);/*** Involves a user with a task. The type of identity link is defined by the given identityLinkType.* @param userId id of the user involve, cannot be null.* @param identityLinkType type of identityLink, cannot be null (@see {@link IdentityLinkType}).* @throws ActivitiObjectNotFoundException when the task or user doesn't exist.*/void addUserIdentityLink(String userId, String identityLinkType);/*** Involves a group with group task. The type of identityLink is defined by the given identityLink.* @param groupId id of the group to involve, cannot be null.* @param identityLinkType type of identity, cannot be null (@see {@link IdentityLinkType}).* @throws ActivitiObjectNotFoundException when the task or group doesn't exist.*/void addGroupIdentityLink(String groupId, String identityLinkType);/*** Convenience shorthand for {@link #deleteUserIdentityLink(String, String)}; with type {@link IdentityLinkType#CANDIDATE}* @param userId id of the user to use as candidate, cannot be null.* @throws ActivitiObjectNotFoundException when the task or user doesn't exist.*/void deleteCandidateUser(String userId);/*** Convenience shorthand for {@link #deleteGroupIdentityLink(String, String, String)}; with type {@link IdentityLinkType#CANDIDATE}* @param groupId id of the group to use as candidate, cannot be null.* @throws ActivitiObjectNotFoundException when the task or group doesn't exist.*/void deleteCandidateGroup(String groupId);/*** Removes the association between a user and a task for the given identityLinkType.* @param userId id of the user involve, cannot be null.* @param identityLinkType type of identityLink, cannot be null (@see {@link IdentityLinkType}).* @throws ActivitiObjectNotFoundException when the task or user doesn't exist.*/void deleteUserIdentityLink(String userId, String identityLinkType);/*** Removes the association between a group and a task for the given identityLinkType.* @param groupId id of the group to involve, cannot be null.* @param identityLinkType type of identity, cannot be null (@see {@link IdentityLinkType}).* @throws ActivitiObjectNotFoundException when the task or group doesn't exist.*/void deleteGroupIdentityLink(String groupId, String identityLinkType);/*** Retrieves the candidate users and groups associated with the task.* @return set of {@link IdentityLink}s of type {@link IdentityLinkType#CANDIDATE}.*/Set<IdentityLink> getCandidates();
}

4. 监听实现方式——表达式expression

使用activiti:taskListener元素的expression属性来指定监听器

4.1 普通表达式

4.1.1  定义表达式类

package org.jeecg.modules.activiti.ext.expression;import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;import java.io.Serializable;@Slf4j
public class TaskListenerExpression implements Serializable {private static final long serialVersionUID = 6880733208262796584L;public void execute(DelegateTask delegateTask) {log.info("creattime: {}", delegateTask.getCreateTime());log.info("getProcessInstanceId: {}", delegateTask.getProcessInstanceId());log.info("数据库中的taskId主键: {}", delegateTask.getId());log.info("任务名称: {}", delegateTask.getName());delegateTask.setName("修改任务名称");log.info("获取任务的描述信息: {}", delegateTask.getDescription());delegateTask.setDescription("修改任务的描述信息");/*** lower priority: [0..19] lowest, [20..39] low, [40..59] normal, [60..79] high* [80..100] highest任务处理的优先级范围是0-100*/log.info("任务处理的优先级范围是0-100: {}", delegateTask.getPriority());delegateTask.setPriority(1); /** 修改优先级*/log.info("获取流程实例id: {}", delegateTask.getProcessInstanceId());log.info("获取流程获取执行id: {}", delegateTask.getExecutionId());log.info("获取流程定义id: {}", delegateTask.getProcessDefinitionId());/** 添一个加候选人 *///void addCandidateUser(String userId);/** 添加候选人集合 *///void addCandidateUsers(Collection<String> candidateUsers);/** 添加候选组 *///void addCandidateGroup(String groupId);String eventName = delegateTask.getEventName();if (TaskListener.EVENTNAME_CREATE.endsWith(eventName)) {System.out.println("create=========");} else if (TaskListener.EVENTNAME_ASSIGNMENT.endsWith(eventName)) {System.out.println("assignment========");} else if (TaskListener.EVENTNAME_COMPLETE.endsWith(eventName)) {System.out.println("complete===========");} else if (TaskListener.EVENTNAME_DELETE.endsWith(eventName)) {System.out.println("delete=============");}}
}

4.1.2 xml定义

4.1.3 如何调用

在流程执行到某个阶段,或者启动流程实例的时候,用下面代码调用

Map<String,Object> map=new HashMap<>();
map.put("taskListenerExpression",new TaskListenerExpression());
runtimeService.startProcessInstanceByKey("taskListener_study2",map);

4.2 spring表达式

spring表达式只是对4.1的优化处理,我们只需要在自己定义的TaskListenerExpression类上加注解管理该bean。在表达式中直接调用。如下其他都不用改表:


@Slf4j
@Service("listenerSpringExpression")
public class TaskListenerExpression implements Serializable {private static final long serialVersionUID = 6880733208262796584L;public void execute(DelegateTask delegateTask) {log.info("creattime: {}", delegateTask.getCreateTime());log.info("getProcessInstanceId: {}", delegateTask.getProcessInstanceId());

xml处的调用也不需要改变。当任务执行到该节点的时候,会直接调用该spring管理的bean。

5. 监听器实现方式——委托表达式delegateExpression

委托表达式 和 表达式区别:

(1)委托表达式需要实现TaskListener和序列化接口

(2)xml中直接写实现类的变量名,不用写方法名称,默认调取接口方法名

5.1 表达式类的实现

package org.jeecg.modules.activiti.ext.expression;import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;import java.io.Serializable;/*** 监听器 委托表达式的实现*/
@Slf4j
public class TaskListenerDelegateExpression implements TaskListener,Serializable {private static final long serialVersionUID = 6880733208262796584L;public void notify(DelegateTask delegateTask) {log.info("creattime: {}", delegateTask.getCreateTime());log.info("getProcessInstanceId: {}", delegateTask.getProcessInstanceId());log.info("数据库中的taskId主键: {}", delegateTask.getId());log.info("任务名称: {}", delegateTask.getName());delegateTask.setName("修改任务名称");log.info("获取任务的描述信息: {}", delegateTask.getDescription());delegateTask.setDescription("修改任务的描述信息");/*** lower priority: [0..19] lowest, [20..39] low, [40..59] normal, [60..79] high* [80..100] highest任务处理的优先级范围是0-100*/log.info("任务处理的优先级范围是0-100: {}", delegateTask.getPriority());delegateTask.setPriority(1); /** 修改优先级*/log.info("获取流程实例id: {}", delegateTask.getProcessInstanceId());log.info("获取流程获取执行id: {}", delegateTask.getExecutionId());log.info("获取流程定义id: {}", delegateTask.getProcessDefinitionId());/** 添一个加候选人 *///void addCandidateUser(String userId);/** 添加候选人集合 *///void addCandidateUsers(Collection<String> candidateUsers);/** 添加候选组 *///void addCandidateGroup(String groupId);String eventName = delegateTask.getEventName();if (TaskListener.EVENTNAME_CREATE.endsWith(eventName)) {System.out.println("create=========");} else if (TaskListener.EVENTNAME_ASSIGNMENT.endsWith(eventName)) {System.out.println("assignment========");} else if (TaskListener.EVENTNAME_COMPLETE.endsWith(eventName)) {System.out.println("complete===========");} else if (TaskListener.EVENTNAME_DELETE.endsWith(eventName)) {System.out.println("delete=============");}}
}

5.2 xml流程文件的定义

<userTask id="sid-11585CC1-BD05-4589-8379-78A6EFA8DCCC" name="县区控尘办审批"><extensionElements><activiti:taskListener event="create" delegateExpression="${taskListenerDelegateExpression}"></activiti:taskListener></extensionElements>
</userTask>

5.3 监听器的使用

在流程到达该任务节点时,就会从流程变量中获取taskListenerDelegateExpression,并执行notify方法

Map<String,Object> map=new HashMap<>();
map.put("taskListenerDelegateExpression",new TaskListenerDelegateExpression());
runtimeService.startProcessInstanceByKey("taskListener_study2",map);

6. 字段属性使用

6.1 xml文件定义

<userTask id="sid-D92E1931-D96E-41EF-AF34-5FC059076F1D" name="办事处审批"><extensionElements><activiti:taskListener event="complete" class="org.jeecg.modules.activiti.ext.listener.SiteReportUserTask"><activiti:field name="fieldNameA"><activiti:string><![CDATA[我是字符串内容666]]></activiti:string></activiti:field></activiti:taskListener></extensionElements>
</userTask>

通过多次设置字段的值可以得知:

fieldNameA取值优先级: 第1个 字符串>第3个 字符串> 第二个 表达式

6.2 类中使用

@Slf4j
public class SiteReportUserTask implements TaskListener {private static final long serialVersionUID = 3654543511891213996L;private Expression fieldNameA;@Overridepublic void notify(DelegateTask delegateTask) {Object o=fieldNameA.getValue(delegateTask);String str=fieldNameA.getExpressionText();... ...

若在表达式中输入:${1==1},则上述代码输出是:o:true;str:${1==1}。自己体会,一个是值,一个是内容字符串。

7. 总结

  1. 一个用户任务节点可以创建多个监听器
  2. class类方式实现监听器,不需要在流程变量中加入监听器对象
  3. expression方式,监听器可以是一个普通的java类,但要实现序列化接口,需要在流程变量中加入监听器类的对象,或者加入spring容器中
  4. delegateExpression,监听器要同时实现TaskListener和序列化接口,需要在流程变量中加入监听器类的对象

5.2 activiti任务监听器TaskListener相关推荐

  1. 5.1 activiti执行监听器ExecutionListener

    1. 执行监听器的使用场景 1.1 人员动态分配 节点审批人员需要在流程运行过程中动态分配 当前任务节点完成的时候,指定需要指定下一个节点的处理人(比如,一个请假流程,a员工请假,需要指定下一步需要处 ...

  2. activiti监听器使用

    分享牛原创(尊重原创 转载对的时候第一行请注明,转载出处来自分享牛http://blog.csdn.net/qq_30739519) activiti使用的时候,通常需要跟业务紧密的结合在一起,有些业 ...

  3. activiti——监听器

    监听器是Activiti在BPMN2.0规范基础上扩展的宫嗯那个,是业务与流程的"非侵入性粘合剂". 监听器可以分未两类:执行监听器和任务监听器,和其他的Activiti扩展模型一 ...

  4. JAVAWEB开发之工作流详解(二)——Activiti核心API的使用(流程定义和流程实例的管理、流程变量、监听器...)以及与Spring的集成

    管理流程定义 设计流程定义文档 bpmn文件 设置方式可以直接使用插件图形化界面进行设置 为某任务节点指定任务执行者 保存后的BPMN文件可以使用XML编辑器打开 BPMN 2.0根节点是defini ...

  5. 《Activiti工作流框架》专题(七)-Activiti工作流框架监听器(listener)

    文章目录 1.监听器概述 2.执行监听器(ExecutionListener) 3.任务监听器(TaskListener) 1.监听器概述 在流程中我们有时会对整个流程或者一个节点的某种状态做出相应的 ...

  6. activiti个人任务分配,UEL表达式,监听器分配,任务查询

    文章目录 一.个人任务 1..分配任务负责人 1.1.固定分配 1.2.表达式分配 1.2.1.UEL 表达式 1)UEL-value 定义 2)UEL-method 方式 3)UEL-method ...

  7. 工作流引擎 Activiti 万字详细进阶

    Activiti进阶 一.流程实例 什么是流程实例 流程实例(ProcessInstance)代表流程定义的执行实例. 一个流程实例包括了所有的运行节点.我们可以利用这个对象来了解当前流程实例的进度等 ...

  8. Activiti总体框架分析

    参考资料 activiti数据表结构 Activiti 5.16 用户手册 Activiti User Guide activiti与BPMN activiti源码 activiti_doc文档 En ...

  9. Activiti工作流之个人任务分配模式

    1.固定分配 在进行业务流程建模时指定固定的任务负责人. 在 properties 视图中,填写 Assignee 项为任务负责人 由于固定分配方式,任务只管一步一步执行任务,执行到每一个任务将按照 ...

最新文章

  1. 最基本的Socket编程 C#版
  2. dubbo+zookeeper+spring实例
  3. webview检测html事件,在JavaFX WebView中检测HTML textarea onkeyup事件
  4. flume数据采集:js埋点
  5. 人工智能AI实战100讲(一)-机器人语义建图(上)
  6. java中函数过载,Java继承中成员方法的overload(重载/过载)
  7. Flutter进阶—创建有状态控件
  8. 给 console 添加颜色
  9. [原]浅谈几种服务器端模型——反应堆模式(epoll 简介) - _Boz - 博客园
  10. python-day1-用户的输入输出
  11. 小D课堂 - 新版本微服务springcloud+Docker教程_2_03常见的微服务框架
  12. python-线程互斥锁与递归锁
  13. wordpress如何在多说评论框中设置圆形旋转头像?
  14. python生日快乐代码简单_Python编程代码:当你的亲人朋友生日时,给他运行这个程序,生日快乐弹窗!...
  15. android 日历动态图标,android 日历图标显示星期
  16. 软考时间管理思维导图
  17. Java播放语音包 亲测
  18. 2023年北京师范大学应用统计考研上岸前辈备考经验指导
  19. Android xml里面product的值来自哪里以及怎么影响编译?
  20. (5)CC3200学习之串口

热门文章

  1. ibatis Clob
  2. 用 vue-cli 手脚架 建立一个 webpack 模板 vue 项目
  3. 500年前的北大寺物证
  4. unity3D实现录音功能,并将真实录音时长保存至本地(不能用可私信,附可执行文件下载地址)
  5. 电信增值短信,彩信平台软件2013年,我司平台软件提供,售后1年期技术维护,客户名单
  6. java中的集合详解
  7. Java秒杀系统实战系列~基于Redisson的分布式锁优化秒杀逻辑
  8. 湿度传感器行业调研报告 - 市场现状分析与发展前景预测
  9. 数据结构判断题30道含答案
  10. (翻译)适当挑战(Appropriate challenge)