Activiti引擎中的事件机制允许您在引擎内发生各种事件时得到通知。查看所有支持的事件类型以了解可用事件的概述。
注册侦听器的3种方式:
- 通过配置添加事件侦听器
- 可以使用API在运行时添事件侦听器
- 将事件侦听器添加到BPMN XML中的流程定义
所有派发出去的事件都是org.activiti.engine.delegate.event.ActivitiEvent的一个子类
。该事件暴露了(如果有的话)type
,executionId
,processInstanceId
和processDefinitionId
。某些事件包含与发生的事件相关的附加上下文,可在所有支持的事件类型列表中找到有关附加内容的附加信息。
实现事件监听器
事件监听器的唯一要求是实现org.activiti.engine.delegate.event.ActivitiEventListener
。下面是一个监听器的示例实现:
public class MyEventListener implements ActivitiEventListener { @Override public void onEvent(ActivitiEvent 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() { // The logic in the onEvent method of this listener is not critical, exceptions // can be ignored if logging fails... return false; } }
isFailOnException方法:如果返回false则当onEvent抛出异常时会被忽略;如果返回true,则异常会向上抛出。如果事件处理是事务中的一部分,则事务将被回滚。如果事件侦听器中的行为不是关键业务,则建议返回false
。
Activiti提供了几个基本实现:
-
org.activiti.engine.delegate.event.BaseEntityEventListener:一个事件侦听器基类,可用于侦听特定类型实体或所有实体的实体相关事件。它隐藏掉类型检查,并提供4种方法:
onCreate(..)
,onUpdate(..),
onDelete(..)
创建,更新或删除实体。对于所有其他与实体相关的事件,onEntityEvent(..) 都会
被调用。
配置
如果在流程引擎配置中配置了事件侦听器,则在流程引擎启动时它将处于活动状态。
该属性eventListeners
需要一个org.activiti.engine.delegate.event.ActivitiEventListener
实例列表。下面的代码片段将一个事件监听器添加到配置中,当任何事件被发送时,它都会被通知,不管它的类型是什么:
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"> ... <property name="eventListeners"> <list> <bean class="org.activiti.engine.example.MyEventListener" /> </list> </property> </bean>
要在特定类型的事件被发送时获得通知,请使用typedeventlistener属性,该属性需要一个map。key就是逗号分割的事件名,value就是org.activiti.engine.delegate.event.ActivitiEventListener实例的列表。下面的代码片段将事件侦听器添加到配置中,当作业执行成功或失败时,将通知它:
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"> ... <property name="typedEventListeners"> <map> <entry key="JOB_EXECUTION_SUCCESS,JOB_EXECUTION_FAILURE" > <list> <bean class="org.activiti.engine.example.MyJobEventListener" /> </list> </entry> </map> </property> </bean>
调度事件的顺序取决于添加侦听器的顺序。首先,eventListeners
属性定义的列表中的bean会按照添加的顺序被调用。在此之后,typedEventListeners属性中如果存在匹配的事件类型,则也会按照添加bean的顺序被调用。
在运行时添加侦听器
通过使用API(RuntimeService
)可以添加或删除事件监听器
/** * Adds an event-listener which will be notified of ALL events by the dispatcher. * @param listenerToAdd the listener to add */ void addEventListener(ActivitiEventListener listenerToAdd); /** * Adds an event-listener which will only be notified when an event occurs, which type is in the given types. * @param listenerToAdd the listener to add * @param types types of events the listener should be notified for */ void addEventListener(ActivitiEventListener listenerToAdd, ActivitiEventType... types); /** * Removes the given listener from this dispatcher. The listener will no longer be notified, * regardless of the type(s) it was registered for in the first place. * @param listenerToRemove listener to remove */ void removeEventListener(ActivitiEventListener listenerToRemove);
将侦听器添加到流程定义
下面的代码片段将两个侦听器添加到一个流程定义中。第一个侦听器将接收任何类型的事件,是监听器的一个实现。第二个侦听器只在任务成功执行或失败时通知,该监听器是是流程引擎配置文件中beans属性定义的一个实例。
<process id="testEventListeners"> <extensionElements> <activiti:eventListener class="org.activiti.engine.test.MyEventListener" /> <activiti:eventListener delegateExpression="${testEventListener}" events="JOB_EXECUTION_SUCCESS,JOB_EXECUTION_FAILURE" /> </extensionElements> ... </process>
对于与实体相关的事件,也可以将侦听器添加到一个流程定义中,该流程定义只在特定实体类型发生实体事件时得到通知。下面的代码片段展示了如何实现这一点。它可以用于所有实体事件(第一个示例)或仅用于特定事件类型(第二个示例)。
<process id="testEventListeners"> <extensionElements> <activiti:eventListener class="org.activiti.engine.test.MyEventListener" entityType="task" /> <activiti:eventListener delegateExpression="${testEventListener}" events="ENTITY_CREATED" entityType="task" /> </extensionElements> ... </process>
entityType
支持的类型包括:attachment
, comment
, execution
, identity-link
, job
, process-instance
, process-definition
, task
.
处理被分派事件的另一种方式是抛出BPMN事件。请记住,使用某些类型的Activiti事件类型来抛出bpmn事件是有意义的。例如,在删除流程实例时抛出BPMN事件将导致错误。下面的代码片段展示了如何在流程实例中抛出一个信号,向外部进程(全局)抛出一个信号,在流程实例中抛出消息事件,并在流程实例中抛出一个错误事件。除了使用class
或class
,还可以使用了属性throwEvent,加上一些额外的属性,用于区别将要抛出事件的类型。
<process id="testEventListeners"> <extensionElements> <activiti:eventListener throwEvent="signal" signalName="My signal" events="TASK_ASSIGNED" /> </extensionElements> </process>
<process id="testEventListeners"> <extensionElements> <activiti:eventListener throwEvent="globalSignal" signalName="My signal" events="TASK_ASSIGNED" /> </extensionElements> </process>
<process id="testEventListeners"> <extensionElements> <activiti:eventListener throwEvent="message" messageName="My message" events="TASK_ASSIGNED" /> </extensionElements> </process>
<process id="testEventListeners"> <extensionElements> <activiti:eventListener throwEvent="error" errorCode="123" events="TASK_ASSIGNED" /> </extensionElements> </process>
如果需要额外的逻辑来决定是否抛出bpmn事件,那么可以扩展Activiti提供的侦听器类。通过在你的子类中覆写isValidEvent(ActivitiEvent event) 可以阻止BPMN-event throwing抛出,这些类包括:org.activiti.engine.test.api.event.SignalThrowingEventListenerTest
,org.activiti.engine.impl.bpmn.helper.MessageThrowingEventListener
和org.activiti.engine.impl.bpmn.helper.ErrorThrowingEventListener
。
在流程定义上的使用监听器需要注意的地方:
- 事件侦听器只能在
process
元素上声明,命名为extensionElements的子元素。 在delegateExpression
中使用的Expressions没有访问执行上下文的权限。他们只能引用流程引擎配置中的beans属性中定义的bean或者引用spring容器中(没有配置beans属性时)任何实现了监听器接口的类- 当使用侦听器元素的class属性时,只会创建该类的单个实例。确保侦听器实现不依赖于成员字段或确保来自多个线程/上下文的安全使用。
- 当在events属性或非法的throwEvent值中使用非法事件类型时,将在部署流程定义时抛出异常(流程定义发布失败)。当
class
或delegateExecution
的非法值被提供(不存在的类、不存在的bean引用或没有实现侦听器接口的委托)时,将在流程启动时抛出异常(或该流程定义的第一个事件被派发给侦听器时)。
通过API分派事件
RuntimeService
/** * Dispatches the given event to any listeners that are registered. * @param event event to dispatch. * * @throws ActivitiException if an exception occurs when dispatching the event or when the {@link ActivitiEventDispatcher} * is disabled. * @throws ActivitiIllegalArgumentException when the given event is not suitable for dispatching. */ void dispatchEvent(ActivitiEvent event);
支持的事件类型
org.activiti.engine.delegate.event.ActivitiEventType
活动名称 | 描述 | 事件类 |
---|---|---|
ENGINE_CREATED |
这个监听器所连接的流程引擎已经被创建并准备好接受API调用。 |
|
ENGINE_CLOSED |
这个监听器所附的进程引擎已关闭。对引擎的API调用不再可能。 |
|
ENTITY_CREATED |
一个新的实体被创建。新的实体包含在事件中。 |
|
ENTITY_INITIALIZED |
一个新的实体已经创建并完全初始化。如果任何儿童是作为创建实体的一部分而创建的,则此事件将在创建/初始化子实体之后被触发,而不是 |
|
ENTITY_UPDATED |
现有更新。更新的实体包含在事件中。 |
|
ENTITY_DELETED |
现有的实体被删除。被删除的实体包含在事件中。 |
|
ENTITY_SUSPENDED |
现有的实体已被暂停。暂停的实体包含在事件中。将派发ProcessDefinitions,ProcessInstances和Tasks。 |
|
ENTITY_ACTIVATED |
现有实体已激活。激活的实体包含在事件中。将派发ProcessDefinitions,ProcessInstances和Tasks。 |
|
JOB_EXECUTION_SUCCESS |
作业已成功执行。该事件包含已执行的作业。 |
|
JOB_EXECUTION_FAILURE |
作业的执行失败。该事件包含已执行的作业和异常。 |
|
JOB_RETRIES_DECREMENTED |
由于作业失败,作业重试次数已减少。该事件包含已更新的作业。 |
|
TIMER_FIRED |
计时器已被解雇。该事件包含已执行的作业? |
|
JOB_CANCELED |
工作已被取消。该事件包含被取消的作业。在新的流程定义部署中,可以通过API调用取消作业,完成任务并取消关联的边界计时器。 |
|
ACTIVITY_STARTED |
活动正在开始执行 |
|
ACTIVITY_COMPLETED |
活动已成功完成 |
|
ACTIVITY_CANCELLED |
一项活动将被取消。活动取消有三个原因(MessageEventSubscriptionEntity,SignalEventSubscriptionEntity,TimerEntity)。 |
|
ACTIVITY_SIGNALED |
活动收到信号 |
|
ACTIVITY_MESSAGE_RECEIVED |
活动收到消息。在活动收到消息之前分派。收到后,将根据类型(边界事件或事件子流程启动事件)为此活动分派a |
|
ACTIVITY_ERROR_RECEIVED |
活动已收到错误事件。在活动处理实际错误之前分派。该事件 |
|
UNCAUGHT_BPMN_ERROR |
未捕获的BPMN错误已被抛出。该过程没有针对该特定错误的任何处理程序。该事件 |
|
ACTIVITY_COMPENSATE |
一项活动即将得到补偿。该事件包含将被执行以进行补偿的活动的ID。 |
|
VARIABLE_CREATED |
一个变量已经创建。该事件包含变量名称,值和相关的执行和任务(如果有的话)。 |
|
VARIABLE_UPDATED |
现有变量已更新。该事件包含变量名称,更新的值以及相关的执行和任务(如果有的话)。 |
|
VARIABLE_DELETED |
现有的变量已被删除。该事件包含变量名称,最后一个已知值以及相关的执行和任务(如果有的话)。 |
|
TASK_ASSIGNED |
任务已分配给用户。该事件包含该任务 |
|
TASK_CREATED |
一项任务已经创建。这是在 |
|
TASK_COMPLETED |
一项任务已经完成。这是在 |
|
PROCESS_COMPLETED |
一个过程已经完成。在最后一个活动 |
|
PROCESS_CANCELLED |
一个进程已被取消。在从运行时删除流程实例之前调度。流程实例被API调用取消 |
|
MEMBERSHIP_CREATED |
用户已被添加到组中。该事件包含涉及的用户和组的ID。 |
|
MEMBERSHIP_DELETED |
用户已从组中删除。该事件包含涉及的用户和组的ID。 |
|
MEMBERSHIPS_DELETED |
所有成员将从组中删除。这个事件在成员被移除之前抛出,所以他们仍然可以访问。 |
|
所有ENTITY_*
事件都与实体相关。下面的列表显示了为哪些实体分派哪些实体事件的概述:
-
ENTITY_CREATED, ENTITY_INITIALIZED, ENTITY_DELETED
:附件,评论,部署,执行,组,IdentityLink,作业,模型,ProcessDefinition,ProcessInstance,任务,用户。 -
ENTITY_UPDATED
:附件,部署,执行,组,IdentityLink,作业,模型,ProcessDefinition,ProcessInstance,任务,用户。 -
ENTITY_SUSPENDED, ENTITY_ACTIVATED
:ProcessDefinition,ProcessInstance / Execution,任务。