赵走x博客
网站访问量:151424
首页
书籍
软件
工具
古诗词
搜索
登录
28、API变量
27、查询API
26、API异常策略
25、 流程引擎API与服务
24、事件处理器
23、映射诊断上下文
22、日志
21、配置部署缓存
20、配置在表达式与脚本中可用的bean
19、配置异步历史
18、配置历史
17、作业执行器
16、数据库与表
15、支持的数据库
14、配置JNDI数据源
13、配置数据库
12、ProcessEngineConfiguration bean
11、创建ProcessEngine
10、开始使用Flowable REST API
9、使用历史数据
8、实现JavaDelegate
7、查询与完成任务
6、另一个话题:事务
5、启动流程实例
4、部署流程定义
3、构建命令行程序
2、Flowable是什么?
1、简介
24、事件处理器
资源编号:551144
热度:264
24、Flowable BPMN 用户手册 (v 6.3.0):事件处理器
Flowable引擎中的事件机制可以让你在引擎中发生多种事件的时候得到通知。查看所有支持的事件类型了解可用的事件。 可以只为特定种类的事件注册监听器,而不是在任何类型的事件发送时都被通知。可以通过配置添加引擎全局的事件监听器,在运行时通过API添加引擎全局的事件监听器,也可以在BPMN XML文件为个别流程定义添加事件监听器。 所有被分发的事件都是org.flowable.engine.common.api.delegate.event.FlowableEvent的子类。事件(在可用时)提供type, executionId, processInstanceId与processDefinitionId。部分事件含有关于发生事件的上下文信息。关于事件包含的附加信息,请参阅所有支持的事件类型。 # 1. 实现事件监听器 对事件监听器的唯一要求,是要实现org.flowable.engine.delegate.event.FlowableEventListener接口。下面是一个监听器实现的例子,它将接收的所有事件打印至标准输出,并对作业执行相关的事件特别处理: ``` public class MyEventListener implements FlowableEventListener { @Override public void onEvent(FlowableEvent event) { switch (event.getType()) { case JOB_EXECUTION_SUCCESS: System.out.println("A job well done!"); break; case JOB_EXECUTION_FAILURE: System.out.println("A job has failed..."); break; default: System.out.println("Event received: " + event.getType()); } } @Override public boolean isFailOnException() { // onEvent方法中的逻辑并不重要,可以忽略日志失败异常…… return false; } } ``` isFailOnException()方法决定了当事件分发后,onEvent(..)方法抛出异常时的行为。若返回false,忽略异常;若返回true,异常不会被忽略而会被上抛,使当前执行的命令失败。如果事件是API调用(或其他事务操作,例如作业执行)的一部分,事务将被回滚。如果事件监听器中并不是重要的业务操作,建议返回false。 Flowable提供了少量基础实现,以简化常用的事件监听器使用场景。它们可以被用作监听器的示例或基类: - org.flowable.engine.delegate.event.BaseEntityEventListener: 事件监听器基类,可用来监听实体(entity)相关事件,特定或所有实体的事件都可以。它隐藏了类型检测,提供了4个需要覆盖的方法:onCreate(..), onUpdate(..)与onDelete(..)在实体创建、更新及删除时调用;对所有其他实体相关事件,onEntityEvent(..)会被调用。 # 2. 配置与使用 在流程引擎中配置的事件监听器会在流程引擎启动时生效,引擎重启后也会保持有效。 eventListeners参数为org.flowable.engine.delegate.event.FlowableEventListener类实例的列表(list)。与其他地方一样,你可以声明内联bean定义,也可以用ref指向已有的bean。下面的代码片段在配置中添加了一个事件监听器,无论任何类型的事件分发时,都会得到通知: ```
...
``` 要在特定类型的事件分发时得到通知,使用typedEventListeners参数,值为map。map的key为逗号分隔的事件名字列表(或者一个事件的名字),取值为org.flowable.engine.delegate.event.FlowableEventListener实例的列表。下面的代码片段在配置中添加了一个事件监听器,它会在作业执行成功或失败时得到通知: ```
...
``` 事件分发的顺序由加入监听器的顺序决定。首先,所有普通(eventListeners参数定义的)事件监听器按照在list里的顺序被调用;之后,如果分发的是某类型的事件,则(typedEventListeners 参数定义的)该类型监听器被调用。 # 3. 在运行时添加监听器 可以使用API(RuntimeService)为引擎添加或删除事件监听器: ``` /** * 新增一个监听器,会在所有事件发生时被通知。 * @param listenerToAdd 要新增的监听器 */ void addEventListener(FlowableEventListener listenerToAdd); /** * 新增一个监听器,在给定类型的事件发生时被通知。 * @param listenerToAdd 要新增的监听器 * @param types 监听器需要监听的事件类型 */ void addEventListener(FlowableEventListener listenerToAdd, FlowableEventType... types); /** * 从分发器中移除指定监听器。该监听器将不再被通知,无论该监听器注册为监听何种类型。 * @param listenerToRemove 要移除的监听器 */ void removeEventListener(FlowableEventListener listenerToRemove); ``` 请注意,运行时新增的监听器在引擎重启后不会保持。 # 4. 为流程定义增加监听器 可以为某一流程定义增加监听器。只有与该流程定义相关,或使用该流程定义启动的流程实例相关的事件,才会调用这个监听器。监听器实现可以用完全限定类名(fully qualified classname)定义;也可以定义为表达式,该表达式需要能被解析为实现监听器接口的bean;也可以配置为抛出消息(message)/信号(signal)/错误(error)的BPMN事件。 ### 执行用户定义逻辑的监听器 下面的代码片段为流程定义增加了2个监听器。第一个监听器接收任何类型的事件,使用完全限定类名定义。第二个监听器只在作业成功执行或失败时被通知,使用流程引擎配置中beans参数定义的bean作为监听器。 ```
...
``` 实体相关的事件也可以在流程定义中增加监听器,只有在特定实体类型的事件发生时得到通知。下面的代码片段展示了如何设置。可以响应实体的所有事件(第一个例子),或只响应实体的特定类型事件(第二个例子)。 ```
...
``` entityType可用的值有:attachment(附件), comment(备注), execution(执行), identity-link(身份关联), job(作业), process-instance(流程实例), process-definition(流程定义), task(任务)。 # 抛出BPMN事件的监听器 处理分发的事件的另一个方法,是抛出BPMN事件。请牢记在心,只有特定种类的Flowable事件类型,抛出BPMN事件才合理。例如,在流程实例被删除时抛出BPMN事件,会导致错误。下面的代码片段展示了如何在流程实例中抛出信号,向外部流程(全局)抛出信号,在流程实例中抛出消息事件,以及在流程实例中抛出错误事件。这里不使用class或delegateExpression,而要使用throwEvent属性,以及一个附加属性,用于指定需要抛出的事件类型。 ```
``` ```
``` ```
``` ```
``` 如果需要使用额外的逻辑判断是否需要抛出BPMN事件,可以扩展Flowable提供的监听器类。通过在你的子类中覆盖isValidEvent(FlowableEvent event),可以阻止抛出BPMN事件。相关的类为org.flowable.engine.test.api.event.SignalThrowingEventListenerTest, org.flowable.engine.impl.bpmn.helper.MessageThrowingEventListener与org.flowable.engine.impl.bpmn.helper.ErrorThrowingEventListener. ### 关于流程定义监听器的说明 - 事件监听器只能作为extensionElements的子元素,声明在process元素上。不能在个别节点(activity)上定义(事件)监听器。 - delegateExpression中的表达式,与其他表达式(例如在网关中的)不一样,不可以访问执行上下文。只能够引用在流程引擎配置中beans参数定义的bean;或是在使用spring(且没有定义beans参数)时,引用任何实现了监听器接口的spring bean。 - 使用监听器的class属性时,只会创建唯一一个该类的实例。请确保监听器实现不依赖于成员变量,或确保多线程/上下文的使用安全。 - 如果events属性使用了不合法的事件类型,或者使用了不合法的throwEvent值,会在流程定义部署时抛出异常(导致部署失败)。如果class或delegateExecution指定了不合法的值(不存在的类,不存在的bean引用,或者代理类没有实现监听器接口),在流程启动(或该流程定义的第一个有效事件分发给这个监听器)时,会抛出异常。请确保引用的类在classpath中,并且保证表达式能够解析为有效的实例。 # 5. 通过API分发事件 可以通过API提供事件分发机制,向任何在引擎中注册的监听器分发自定义事件。建议(但不强制)只分发CUSTOM类型的FlowableEvents。使用RuntimeService分发事件: ``` /** * 将给定事件分发给所有注册监听器。 * @param event 要分发的事件。 * * @throws FlowableException 当分发事件发生异常,或者{@link FlowableEventDispatcher}被禁用。 * @throws FlowableIllegalArgumentException 当给定事件不可分发 */ void dispatchEvent(FlowableEvent event); ``` # 6. 支持的事件类型 下表列出引擎中的所有事件类型。每种类型对应org.flowable.engine.common.api.delegate.event.FlowableEventType中的一个枚举值。 Table 1. Supported events | 事件名称 | 说明 | 事件类 | | :------------ | :------------ | :------------ | |ENGINE_CREATED|本监听器所属的流程引擎已经创建,并可以响应API调用。|org.flowable…FlowableEvent| |ENGINE_CLOSED|本监听器所属的流程引擎已经关闭,不能再对该引擎进行API调用。|org.flowable…FlowableEvent| |ENTITY_CREATED|新的实体已经创建。该实体包含在本事件里。|org.flowable…FlowableEntityEvent| |ENTITY_INITIALIZED|新的实体已经创建并完全初始化。如果任何子实体作为该实体的一部分被创建,本事件会在子实体创建/初始化后触发,与 ENTITY_CREATE 事件相反。|org.flowable…FlowableEntityEvent| |ENTITY_UPDATED|实体已经更新。该实体包含在本事件里。|org.flowable…FlowableEntityEvent| |ENTITY_DELETED|实体已经删除。该实体包含在本事件里。|org.flowable…FlowableEntityEvent| |ENTITY_SUSPENDED|实体已经暂停。该实体包含在本事件里。ProcessDefinitions(流程定义), ProcessInstances(流程实例)与Tasks(任务)会分发本事件。|org.flowable…FlowableEntityEvent| |ENTITY_ACTIVATED|实体已经激活。该实体包含在本事件里。ProcessDefinitions, ProcessInstances与Tasks会分发本事件。|org.flowable…FlowableEntityEvent| |JOB_EXECUTION_SUCCESS|作业已经成功执行。该作业包含在本事件里。|org.flowable…FlowableEntityEvent| |JOB_EXECUTION_FAILURE|作业执行失败。该作业与异常包含在本事件里。|org.flowable…FlowableEntityEvent 及 org.flowable…FlowableExceptionEvent| |JOB_RETRIES_DECREMENTED|作业重试次数已经由于执行失败而减少。该作业包含在本事件里。|org.flowable…FlowableEntityEvent| |TIMER_SCHEDULED|已创建一个定时作业,并预计在未来时间点执行。|org.flowable…FlowableEntityEvent| |TIMER_FIRED|定时器已经触发。|org.flowable…FlowableEntityEvent| |JOB_CANCELED|作业已经取消。该作业包含在本事件里。作业会由于API调用取消,任务完成导致关联的边界定时器取消,也会由于新流程定义的部署而取消。|org.flowable…FlowableEntityEvent| |ACTIVITY_STARTED|节点开始执行|org.flowable…FlowableActivityEvent| |ACTIVITY_COMPLETED|节点成功完成|org.flowable…FlowableActivityEvent| |ACTIVITY_CANCELLED|节点将要取消。节点的取消有三个原因(MessageEventSubscriptionEntity, SignalEventSubscriptionEntity, TimerEntity)。|org.flowable…FlowableActivityCancelledEvent| |ACTIVITY_SIGNALED|节点收到了一个信号|org.flowable…FlowableSignalEvent| |ACTIVITY_MESSAGE_RECEIVED|节点收到了一个消息。事件在节点接收消息前分发。节点接收消息后,会为该节点分发 ACTIVITY_SIGNAL 或 ACTIVITY_STARTED 事件,取决于其类型(边界事件,或子流程启动事件)。|org.flowable…FlowableMessageEvent| |ACTIVITY_MESSAGE_WAITING|一个节点已经创建了一个消息事件订阅,并正在等待接收消息。|org.flowable…FlowableMessageEvent| |ACTIVITY_MESSAGE_CANCELLED|一个节点已经取消了一个消息事件订阅,因此接收这个消息不会再触发该节点。|org.flowable…FlowableMessageEvent| |ACTIVITY_ERROR_RECEIVED|节点收到了错误事件。在节点实际处理错误前分发。该事件的activityId为处理错误的节点。如果错误成功传递,后续会为节点发送 ACTIVITY_SIGNALLED 或 ACTIVITY_COMPLETE 消息。|org.flowable…FlowableErrorEvent| |UNCAUGHT_BPMN_ERROR|抛出了未捕获的BPMN错误。流程没有该错误的处理器。该事件的activityId为空。|org.flowable…FlowableErrorEvent| |ACTIVITY_COMPENSATE|节点将要被补偿(compensate)。该事件包含将要执行补偿的节点id。|org.flowable…FlowableActivityEvent| |MULTI_INSTANCE_ACTIVITY_STARTED|多实例节点开始执行|org.flowable…FlowableMultiInstanceActivityEvent| |MULTI_INSTANCE_ACTIVITY_COMPLETED|多实例节点成功完成|org.flowable…FlowableMultiInstanceActivityEvent| |MULTI_INSTANCE_ACTIVITY_CANCELLED|多实例节点将要取消。多实例节点的取消有三个原因(MessageEventSubscriptionEntity, SignalEventSubscriptionEntity, TimerEntity)。|org.flowable…FlowableMultiInstanceActivityCancelledEvent| |VARIABLE_CREATED|流程变量已经创建。本事件包含变量名、取值,及关联的执行和任务(若有)。|org.flowable…FlowableVariableEvent| |VARIABLE_UPDATED|变量已经更新。本事件包含变量名、取值,及关联的执行和任务(若有)。|org.flowable…FlowableVariableEvent| |VARIABLE_DELETED|变量已经删除。本事件包含变量名、最后取值,及关联的执行和任务(若有)。|org.flowable…FlowableVariableEvent| |TASK_ASSIGNED|任务已经分派给了用户。该任务包含在本事件里。|org.flowable…FlowableEntityEvent| |TASK_CREATED|任务已经创建。本事件在 ENTITY_CREATE 事件之后分发。若该任务是流程的一部分,本事件会在任务监听器执行前触发。|org.flowable…FlowableEntityEvent| |TASK_COMPLETED|任务已经完成。本事件在 ENTITY_DELETE 事件前分发。若该任务是流程的一部分,本事件会在流程前进之前触发,并且会跟随一个 ACTIVITY_COMPLETE 事件,指向代表该任务的节点。|org.flowable…FlowableEntityEvent| |PROCESS_CREATED|流程实例已经创建。已经设置所有的基础参数,但还未设置变量。|org.flowable…FlowableEntityEvent| |PROCESS_STARTED|流程实例已经启动。在启动之前创建的流程时分发。PROCESS_STARTED事件在相关的ENTITY_INITIALIZED事件,以及设置变量之后分发。| org.flowable…FlowableEntityEvent| |PROCESS_COMPLETED|流程实例已经完成。在最后一个节点的 ACTIVITY_COMPLETED 事件后分发。当流程实例没有任何路径可以继续时,流程结束。|org.flowable…FlowableEntityEvent| |PROCESS_COMPLETED_WITH_TERMINATE_END_EVENT|流程已经到达终止结束事件(terminate end event)并结束。|org.flowable…FlowableProcessTerminatedEvent| |PROCESS_CANCELLED|流程已经被取消。在流程实例从运行时中删除前分发。流程实例由API调用RuntimeService.deleteProcessInstance取消。|org.flowable…FlowableCancelledEvent| |MEMBERSHIP_CREATED|用户已经加入组。本事件包含了相关的用户和组的id。| |org.flowable…FlowableMembershipEvent| |MEMBERSHIP_DELETED|用户已经从组中移出。本事件包含了相关的用户和组的id。|org.flowable…FlowableMembershipEvent| |MEMBERSHIPS_DELETED|组的所有用户将被移出。本事件在用户移出前抛出,因此关联关系仍然可以访问。因为性能原因,不会再为每个被移出的用户抛出 MEMBERSHIP_DELETED 事件。|org.flowable…FlowableMembershipEvent| 引擎中所有的 ENTITY_\* 事件都与实体关联。下表列出每个实体分发的实体事件: - ENTITY_CREATED, ENTITY_INITIALIZED, ENTITY_DELETED: 附件(Attachment),备注(Comment),部署(Deployment),执行(Execution),组(Group),身份关联(IdentityLink),作业(Job),模型(Model),流程定义(ProcessDefinition),流程实例(ProcessInstance),任务(Task),用户(User)。 - ENTITY_UPDATED: 附件,部署,执行,组,身份关联,作业,模型,流程定义,流程实例,任务,用户。 - ENTITY_SUSPENDED, ENTITY_ACTIVATED: 流程定义,流程实例/执行,任务。 # 7. 附加信息 监听器只会响应其所在引擎分发的事件。因此如果在同一个数据库上运行不同的引擎,则只有该监听器注册的引擎生成的事件,才会分发给该监听器。其他引擎生成的事件不会分发给这个监听器,而不论这些引擎是否运行在同一个JVM下。 某些事件类型(与实体相关)暴露了目标实体。按照事件类型的不同,有些实体不能被更新(如实体删除事件中的实体)。如果可能的话,请使用事件暴露的EngineServices来安全地操作引擎。即使这样,更新、操作事件中暴露的实体仍然需要小心。 历史不会分发实体事件,因为它们都有对应的运行时实体分发事件。