网站建设切片效果是什么,网站开发用什么语言最好,建设永久网站,软文网站推荐文章目录 学习链接任务监听器 TaskListener监听的事件TaskListener 接口监听器委托类DelegateTask 任务监听实现方式 — 类class绘制流程图自定义任务监听器SiteReportUserTaskListener 测试 监听实现方式 — 表达式expression绘制流程图自定义 TaskListenerExpression测试spri… 文章目录 学习链接任务监听器 TaskListener监听的事件TaskListener 接口监听器委托类DelegateTask 任务监听实现方式 — 类class绘制流程图自定义任务监听器SiteReportUserTaskListener 测试 监听实现方式 — 表达式expression绘制流程图自定义 TaskListenerExpression测试spring表达式 监听器实现方式——委托表达式delegateExpression绘制流程图自定义 TaskListenerDelegateExpression测试 字段属性使用自定义类SiteReportUserTaskListener 总结 执行监听器 ExecutionListener执行监听器的使用场景人员动态分配任务节点调取业务流程上处理业务连线上处理业务 监听的事件ExecutionListener 接口DelegateExecution 执行监听器与任务监听器区别工作流程事件监听 ActivitiEventListener 学习链接
Activiti深入研究 - 专栏
5.2 activiti任务监听器TaskListener5.1 activiti执行监听器ExecutionListener5.3 activiti工作流程事件监听ActivitiEventListener
Activiti7工作流从入门到实战(全网最好的)
Activiti7工作流引擎基础篇(六) 任务监听器和流程监听器
Activiti
activiti学习五——执行监听器与任务监听器的基本使用activiti学习十一——全局事件监听器的基本使用及其原理
Activiti之任务监听器与执行监听器详解
程序员一灯-activiti监听器
任务监听器 TaskListener
任务监听器用于在特定的任务相关事件发生时执行自定义的Java逻辑或表达式
任务监听器是处理业务逻辑的重要的地方当任务创建、设定负责人、完成任务时都可以监听的到从而来处理自己的业务常用于监听Assignment事件设置完负责人给负责人发一个消息来通知提示。注意任务监听器只能用在UserTask上使用。
监听的事件 String EVENTNAME_CREATE “create”;创建当任务已经创建并且所有任务参数都已经设置时触发 String EVENTNAME_ASSIGNMENT “assignment”;指派当任务已经指派给某人时触发。请注意当流程执行到达用户任务时create事件触发前首先触发assignment事件。这看起来不是自然顺序但是有实际原因的当收到create事件时我们通常希望查看任务的所有参数包括办理人。 String EVENTNAME_COMPLETE “complete”完成当任务已经完成从运行时数据中删除前触发。 String EVENTNAME_DELETE “delete”删除在任务即将被删除前触发。请注意当任务通过completeTask正常完成时也会触发
注意assignment事件比create先执行。
TaskListener 接口
TaskListener接口继承自BaseTaskListener 接口
public interface BaseTaskListener extends Serializable {String EVENTNAME_CREATE create;String EVENTNAME_ASSIGNMENT assignment;String EVENTNAME_COMPLETE complete;String EVENTNAME_DELETE delete;/*** Not an actual event, used as a marker-value for {link BaseTaskListener}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;
}
TaskListener接口定义只有notify方法传入DelegateTask
public interface TaskListener extends BaseTaskListener {void notify(DelegateTask delegateTask);
}监听器委托类DelegateTask
我们在监听方法中能够拿到DelegateTask对象因此我们要熟悉这个对象的相关方法
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(CollectionString 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(CollectionString 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 doesnt 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 doesnt 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 doesnt 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 doesnt 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 doesnt 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 doesnt 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}.*/SetIdentityLink getCandidates();
}任务监听实现方式 — 类class
绘制流程图 给经理审批节点设置如下任务监听器 自定义任务监听器
SiteReportUserTaskListener
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 SiteReportUserTaskListener implements TaskListener {/*启动流程时候按顺序收到事件通知: assignment收到事件通知: create完成经理审批任务时候按顺序收到事件通知: complete收到事件通知: delete*/Overridepublic void notify(DelegateTask delegateTask) {log.info(收到事件通知: {}, delegateTask.getEventName());}}测试
先部署该流程然后发起1个流程时它会收到assignment、create然后部门经理完成该任务它会收到complete、delete
监听实现方式 — 表达式expression
使用activiti:taskListener元素的expression属性来指定监听器
绘制流程图 如下图给经理审批节点添加任务监听器设置Expression为${taskListenerExpression.execute(task)}
自定义 TaskListenerExpression
注意这个的TaskListenerExpression 需要实现Serializable接口。
Slf4j
public class TaskListenerExpression implements Serializable {public void execute(DelegateTask delegateTask) {log.info(收到事件通知: {}, delegateTask.getEventName());}}测试 先部署该流程 然后发起1个流程时注意发起流程时这里需要设置taskListenerExpression然后它会收到assignment、create ProcessEngine engine ProcessEngines.getDefaultProcessEngine();
// 发起流程 需要通过 runtimeService来实现
RuntimeService runtimeService engine.getRuntimeService();
HashMapString, Object variables new HashMapString, Object();
// 在流程执行到某个阶段或者启动流程实例的时候用下面代码调用
HashMapString, Object variables new HashMapString, Object();
variables.put(taskListenerExpression, new TaskListenerExpression());
ProcessInstance processInstance runtimeService.startProcessInstanceByKey(listener1, variables);然后部门经理完成该任务它会收到complete、delete
spring表达式
在上面我们在开启流程时自己new了1个TaskListenerExpression并且把它放入了流程变量中。在spring中我们只需要将此bean定义在spring容器中即可此处案例定义在activiti.cfg.xml中在启动流程时就不需要把它放入流程变量中了就可以启动流程注意一定要把这个bean定义在容器中否则启动流程时会报错因为此时不能解析表达式了。当任务执行到该节点的时候会直接调用该spring管理的bean。
监听器实现方式——委托表达式delegateExpression
委托表达式 和 表达式区别 委托表达式需要实现TaskListener和序列化接口 xml中直接写实现类的变量名不用写方法名称默认调取接口方法名
绘制流程图 设置经理审批节点当经理审批后触发表达式的执行 自定义 TaskListenerDelegateExpression
需要同时实现TaskListener接口 和 Serializable接口
Slf4j
public class TaskListenerDelegateExpression implements TaskListener, Serializable {Overridepublic void notify(DelegateTask delegateTask) {log.info(TaskListenerDelegateExpression#收到事件通知: {}, delegateTask.getEventName());}
}测试 先部署该流程 然后发起1个流程时注意发起流程时这里需要设置taskListenerDelegateExpression ProcessEngine engine ProcessEngines.getDefaultProcessEngine();
// 发起流程 需要通过 runtimeService来实现
RuntimeService runtimeService engine.getRuntimeService();HashMapString, Object variables new HashMapString, Object();
variables.put(taskListenerDelegateExpression, new TaskListenerDelegateExpression());// 通过流程定义ID来启动流程 返回的是流程实例对象
ProcessInstance processInstance runtimeService.startProcessInstanceByKey(listener1, variables);System.out.println(processInstance.getId() processInstance.getId());
System.out.println(processInstance.getDeploymentId() processInstance.getDeploymentId());
System.out.println(processInstance.getDescription() processInstance.getDescription());然后部门经理完成该任务委托表达式执行它会收到complete ProcessEngine engine ProcessEngines.getDefaultProcessEngine();
TaskService taskService engine.getTaskService();
ListTask list taskService.createTaskQuery().taskAssignee(zhangsan).list();
MapString, Object map new HashMap();
Task task list.get(0);
// 完成经理审批
taskService.complete(task.getId(), map);字段属性使用
下面这种只能用类这种方式来给类中的某个属性赋值
自定义类SiteReportUserTaskListener
Slf4j
public class SiteReportUserTaskListener implements TaskListener {/* 注意这里写的类型否则可能会报错 */private Expression fieldNameA;/*完成经理审批任务时候收到事件通知: complete*/Overridepublic void notify(DelegateTask delegateTask) {log.info(收到事件通知: {}, {}, delegateTask.getEventName(), fieldNameA);}}通过多次设置字段的值可以得知fieldNameA取值优先级 第1个 字符串第3个 字符串 第二个 表达式
总结
一个用户任务节点可以创建多个监听器class类方式实现监听器不需要在流程变量中加入监听器对象expression方式,监听器可以是一个普通的java类但要实现序列化接口,需要在流程变量中加入监听器类的对象或者加入spring容器中delegateExpression,监听器要同时实现TaskListener和序列化接口需要在流程变量中加入监听器类的对象
执行监听器 ExecutionListener
执行监听器的使用场景
人员动态分配
节点审批人员需要在流程运行过程中动态分配当前任务节点完成的时候需要指定下一个节点的处理人(比如一个请假流程a员工请假需要指定下一步需要处理请假流程的领导)
任务节点调取业务 任务节点完成的时候需要一些复杂业务(比如当前节点完成的时候需要调用我们的jms消息系统发送消息)。 任务流转到当前的节点的时候需要监控当前任务节点的一些信息或者其他的业务信息。 当前的任务节点分配处理人的时候需要触发自定义的一些业务。
流程上处理业务
流程开始结束的时候需要处理业务信息。
连线上处理业务
经过任务节点的出线也就是连线的时候需要触发自定义的业务。
监听的事件
ExecutionListener 接口
ExecutionListener 继承自BaseExecutionListener 接口
/*
Callback interface to be notified of execution events like starting a process instance, ending an activity instance,taking a transition.
*/
public interface BaseExecutionListener extends Serializable {String EVENTNAME_START start;String EVENTNAME_END end;String EVENTNAME_TAKE take;
}
ExecutionListener 接口如下
public interface ExecutionListener extends BaseExecutionListener {void notify(DelegateExecution execution);
}DelegateExecution
public interface DelegateExecution extends VariableScope {/*** Unique id of this path of execution that can be used as a handle to provide external signals back into the engine after wait states.*/String getId();/** Reference to the overall process instance */String getProcessInstanceId();/*** The root process instance. When using call activity for example, the processInstance* set will not always be the root. This method returns the topmost process instance.*/String getRootProcessInstanceId();/*** Will contain the event name in case this execution is passed in for an {link ExecutionListener}.*/String getEventName();/*** Sets the current event (typically when execution an {link ExecutionListener}). */void setEventName(String eventName);/*** The business key for the process instance this execution is associated with.*/String getProcessInstanceBusinessKey();/*** The process definition key for the process instance this execution is associated with.*/String getProcessDefinitionId();/*** Gets the id of the parent of this execution. If null, the execution represents a process-instance.*/String getParentId();/*** Gets the id of the calling execution. If not null, the execution is part of a subprocess.*/String getSuperExecutionId();/*** Gets the id of the current activity.*/String getCurrentActivityId();/*** Returns the tenant id, if any is set before on the process definition or process instance.*/String getTenantId();/*** The BPMN element where the execution currently is at. */FlowElement getCurrentFlowElement();/*** Change the current BPMN element the execution is at. */void setCurrentFlowElement(FlowElement flowElement);/*** Returns the {link ActivitiListener} instance matching an {link ExecutionListener}* if currently an execution listener is being execution. * Returns null otherwise.*/ActivitiListener getCurrentActivitiListener();/*** Called when an {link ExecutionListener} is being executed. */void setCurrentActivitiListener(ActivitiListener currentActivitiListener);/* Execution management *//*** returns the parent of this execution, or null if there no parent.*/DelegateExecution getParent();/*** returns the list of execution of which this execution the parent of.*/List? extends DelegateExecution getExecutions();/* State management *//*** makes this execution active or inactive.*/void setActive(boolean isActive);/*** returns whether this execution is currently active.*/boolean isActive();/*** returns whether this execution has ended or not.*/boolean isEnded();/*** changes the concurrent indicator on this execution.*/void setConcurrent(boolean isConcurrent);/*** returns whether this execution is concurrent or not.*/boolean isConcurrent();/*** returns whether this execution is a process instance or not.*/boolean isProcessInstanceType();/*** Inactivates this execution. This is useful for example in a join: the execution still exists, but it is not longer active.*/void inactivate();/*** Returns whether this execution is a scope.*/boolean isScope();/*** Changes whether this execution is a scope or not.*/void setScope(boolean isScope);/*** Returns whather this execution is the root of a multi instance execution.*/boolean isMultiInstanceRoot();/*** Changes whether this execution is a multi instance root or not.* param isMultiInstanceRoot*/void setMultiInstanceRoot(boolean isMultiInstanceRoot);}使用方法与上面大致相同只不过ExecutionListener还可以设置在开始和结束节点、连线上。
执行监听器与任务监听器区别
执行监听器与任务监听器的基本原理和使用方法。当流程途径连线或者节点的时候会触发对应的事件类型。执行监听器与任务监听器在生产中经常会用在几个方面
动态分配节点处理人。通过前一个节点设置的变量在运行到下一个节点时设置对应的处理人当流程运行到某个节点时发送邮件或短信给待办用户统计流程处理时长是否超时等业务层面数据处理。
任务监听器顾名思义是监听任务的。任务监听器的生命周期如下图所示会经历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 version1.0 encodingUTF-8?
definitions xmlnshttp://www.omg.org/spec/BPMN/20100524/MODEL xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:xsdhttp://www.w3.org/2001/XMLSchema xmlns:activitihttp://activiti.org/bpmn xmlns:bpmndihttp://www.omg.org/spec/BPMN/20100524/DI xmlns:omgdchttp://www.omg.org/spec/DD/20100524/DC xmlns:omgdihttp://www.omg.org/spec/DD/20100524/DI typeLanguagehttp://www.w3.org/2001/XMLSchema expressionLanguagehttp://www.w3.org/1999/XPath targetNamespacehttp://www.activiti.org/testprocess idlistenerBpmProcess nameMy process isExecutabletruestartEvent idstartevent1 nameStart/startEventuserTask idusertask1 namemyTask1 activiti:assignee张三extensionElementsactiviti:executionListener eventstart classlistener.MyExecutionListener/activiti:executionListeneractiviti:executionListener eventend classlistener.MyExecutionListener/activiti:executionListeneractiviti:taskListener eventall classlistener.MyTaskListener/activiti:taskListener/extensionElements/userTaskendEvent idendevent1 nameEnd/endEventsequenceFlow idflow1 sourceRefstartevent1 targetRefusertask1/sequenceFlowsequenceFlow idflow2 sourceRefusertask1 targetRefendevent1/sequenceFlow/processbpmndi:BPMNDiagram idBPMNDiagram_listenerBpmProcessbpmndi:BPMNPlane bpmnElementlistenerBpmProcess idBPMNPlane_listenerBpmProcessbpmndi:BPMNShape bpmnElementstartevent1 idBPMNShape_startevent1omgdc:Bounds height41.0 width35.0 x505.0 y40.0/omgdc:Bounds/bpmndi:BPMNShapebpmndi:BPMNShape bpmnElementusertask1 idBPMNShape_usertask1omgdc:Bounds height55.0 width105.0 x470.0 y150.0/omgdc:Bounds/bpmndi:BPMNShapebpmndi:BPMNShape bpmnElementendevent1 idBPMNShape_endevent1omgdc:Bounds height35.0 width35.0 x505.0 y240.0/omgdc:Bounds/bpmndi:BPMNShapebpmndi:BPMNEdge bpmnElementflow1 idBPMNEdge_flow1omgdi:waypoint x522.0 y81.0/omgdi:waypointomgdi:waypoint x522.0 y150.0/omgdi:waypoint/bpmndi:BPMNEdgebpmndi:BPMNEdge bpmnElementflow2 idBPMNEdge_flow2omgdi:waypoint x522.0 y205.0/omgdi:waypointomgdi:waypoint x522.0 y240.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对象期间利用对象解析器动态添加监听器。
工作流程事件监听 ActivitiEventListener