可以为对应的事件类型注册监听器,在这个类型的任何时间触发时都会收到提醒。 你可以添加引擎范围的事件监听器通过, 添加引擎范围的事件监听器在运行阶段使用API, 或添加 event-listener 到。

    所有分发的事件,都是org.activiti.engine.delegate.event.ActivitiEvent 的子类。事件包含(如果有效)type,executionId,processInstanceId 和processDefinitionId。 对应的事件会包含事件发生时对应上下文的额外信息, 这些额外的载荷可以在所有支持的事件类型中找到。

    实现事件监听器的唯一要求是实现org.activiti.engine.delegate.event.ActivitiEventListener。 西面是一个实现监听器的例子,它会把所有监听到的事件打印到标准输出中,包括job执行的事件异常:

    isFailOnException() 方法决定了当事件分发时,onEvent(..) 方法抛出异常时的行为。 这里返回的是 false,会忽略异常。 当返回 true 时,异常不会忽略,继续向上传播,迅速导致当前命令失败。 当事件是一个 API 调用的一部分时(或其他事务性操作,比如 job 执行), 事务就会回滚。当事件监听器中的行为不是业务性时,建议返回 false。 activiti 提供了一些基础的实现,实现了事件监听器的常用场景。可以用来作为基类或监听器实现的样例:

    • org.activiti.engine.delegate.event.BaseEntityEventListener: 这个事件监听器的基
      类可以用来监听实体相关的事件,可以针对某一类型实体,也可以是全部实体。 它隐藏了
      类型检测,并提供了三个需要重写的方法:onCreate(..), onUpdate(..) 和 onDelete(..),当实
      体创建,更新,或删除时调用。对于其他实体相关的事件,会调用 onEntityEvent(..)。

    Configuration and setup 配置和安装

    把事件监听器配置到流程引擎配置中时,会在流程引擎启动时激活,并在引擎启动启动中持续工作着。

    eventListeners 属性需要org.activiti.engine.delegate.event.ActivitiEventListener 的队列。 通常,我们可以声明一个内部的bean定义,或使用 ref 引用已定义的 bean。 下面的代码,向配置添加了一个事件监听器,任何事件触发时都会提醒它,无论事件是什么类型:

    1. ...
    2. <property name="eventListeners">
    3. <list>
    4. <bean class="org.activiti.engine.example.MyEventListener" />
    5. </list>
    6. </property>
    7. </bean>

    为了监听特定类型的事件,可以使用 typedEventListeners 属性,它需要一个 map 参数。 map
    的 key 是逗号分隔的事件名(或单独的事件名)。 map 的 value
    是 org.activiti.engine.delegate.event.ActivitiEventListener 队列。 下面的代码演示了向配置中添加一个事件监听器,可以监听 job 执行成功或失败:

    1. <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
    2. ...
    3. <property name="typedEventListeners">
    4. <map>
    5. <entry key="JOB_EXECUTION_SUCCESS,JOB_EXECUTION_FAILURE" >
    6. <list>
    7. <bean class="org.activiti.engine.example.MyJobEventListener" />
    8. </list>
    9. </entry>
    10. </map>
    11. </property>
    12. </bean>

    可以通过API(RuntimeService)在运行阶段添加或删除额外的事件监听器

    1. /**
    2. * Adds an event-listener which will be notified of ALL events by the dispatcher.
    3. */
    4. void addEventListener(ActivitiEventListener listenerToAdd);
    5. /**
    6. * Adds an event-listener which will only be notified when an event occurs, which type is in the given types.
    7. * @param listenerToAdd the listener to add
    8. * @param types types of events the listener should be notified for
    9. */
    10. void addEventListener(ActivitiEventListener listenerToAdd, ActivitiEventType... types);
    11. /**
    12. * Removes the given listener from this dispatcher. The listener will no longer be notified,
    13. * regardless of the type(s) it was registered for in the first place.
    14. * @param listenerToRemove listener to remove
    15. */

    注意运行期添加的监听器引擎重启后就消失了

    Adding listeners to process definitions 添加监听到流程定义

    可以为特定流程定义添加监听器。监听器只会监听与这个流程定义相关的事件,以及这个流程定义上发起的所有流程实例的事件。 监听器实现可以使用,全类名定义,引用实现了监听器接口的表达式,或配置为抛出一个message/signal/error 的 BPMN 事件。

    Listeners executing user-defined logic 让监听器执行用户定义的逻辑

    下面代码为一个流程定义添加了两个监听器。第一个监听器会接收所有类型的事件,它是通过全类名定义的。 第二个监听器只接收作业成功或失败的事件,它使用了定义在流程引擎配置中的 beans 属性中的一个 bean。

    对于实体相关的事件,也可以设置为针对某个流程定义的监听器,实现只监听发生在某个流程定义上的某个类型实体事件。 下面的代码演示了如何实现这种功能。可以用于所有实体事件(第一个例子),也可以只监听特定类型的事件(第二个例子)

    1. <process id="testEventListeners">
    2. <extensionElements>
    3. <activiti:eventListener class="org.activiti.engine.test.MyEventListener" entityType="task" />
    4. <activiti:eventListener delegateExpression="${testEventListener}" events="ENTITY_CREATED" entityType="task" />
    5. </extensionElements>
    6. ...
    7. </process>

    entityType 支持的值有:attachment, comment, execution,identity-link, job, process-instance,
    process-definition, task。

    1. <process id="testEventListeners">
    2. <extensionElements>
    3. <activiti:eventListener class="org.activiti.engine.test.MyEventListener" entityType="task" />
    4. <activiti:eventListener delegateExpression="${testEventListener}" events="ENTITY_CREATED" entityType="task" />
    5. </extensionElements>
    6. ...

    Listeners throwing BPMN events

    [试验阶段]

    1. <process id="testEventListeners">
    2. <extensionElements>
    3. <activiti:eventListener throwEvent="signal" signalName="My signal" events="TASK_ASSIGNED" />
    4. </extensionElements>
    5. </process>
    1. <process id="testEventListeners">
    2. <extensionElements>
    3. <activiti:eventListener throwEvent="message" messageName="My message" events="TASK_ASSIGNED" />
    4. </extensionElements>
    5. </process>
    1. <process id="testEventListeners">
    2. <extensionElements>
    3. <activiti:eventListener throwEvent="error" errorCode="123" events="TASK_ASSIGNED" />
    4. </extensionElements>
    5. </process>

    如果需要声明额外的逻辑,是否抛出 BPMN 事件,可以扩展 activiti 提供的监听器类。在子类中重写 isValidEvent(ActivitiEvent event), 可以防止抛出 BPMN 事件。对应的类是
    org.activiti.engine.test.api.event.SignalThrowingEventListenerTest,
    org.activiti.engine.impl.bpmn.helper.MessageThrowingEventListener 和
    org.activiti.engine.impl.bpmn.helper.ErrorThrowingEventListener.

    Notes on listeners on a process-definition 流程定义中监听器的注意事项

    • 事件监听器只能声明在 process 元素中,作为 extensionElements 的子元素。 监听器不能定义在流程的单个 activity 下。
    • delegateExpression 中的表达式无法访问 execution 上下文,这与其他表达式不同(比如 gateway )。 它只能引用定义在流程引擎配置的beans 属性中声明的 bean,或者使用 spring(未使用 beans 属性)中所有实现了监听器接口的 spring-bean。
    • 在使用监听器的 class 属性时,只会创建一个实例。记住监听器实现不会依赖成员变量,确认是多线程安全的。
    • 当一个非法的事件类型用在 events 属性或 throwEvent 中时,流程定义发布时就会抛出异常。(会导致部署失败)。如果 class 或delegateExecution 由问题(类不存在,不存在的 bean 引用,或代理类没有实现监听器接口),会在流程启动时抛出异常(或在第一个有效的流程定义事件被监听器接收时)。所以要保证引用的类正确的放在 classpath 下,表达式也要引用一个有效的实例。

    我们提供了通过 API 使用事件机制的方法,允许大家触发定义在引擎中的任何自定义事件。
    建议(不强制)只触发类型为 CUSTOM 的 ActivitiEvents。可以通过RuntimeService 触发事件:

    1. /**
    2. * @param event event to dispatch.
    3. *
    4. * @throws ActivitiException if an exception occurs when dispatching the event or when the {@link ActivitiEventDispatcher}
    5. * is disabled.
    6. * @throws ActivitiIllegalArgumentException when the given event is not suitable for dispatching.
    7. */
    8. void dispatchEvent(ActivitiEvent event);

    下面是引擎中可能出现的所有事件类型。每个类型都对应 org.activiti.engine.delegate.event.ActivitiEventType 中的一个枚举值

    Table 1. Supported events



































    引擎内部所有 ENTITY_* 事件都是与实体相关的。下面的列表展示了实体事件与实体的对应关
    系:

    • ENTITY_CREATED, ENTITY_INITIALIZED, ENTITY_DELETED: Attachment, Comment, Deployment, Execution, Group, IdentityLink, Job, Model, ProcessDefinition, ProcessInstance, Task, User.
    • ENTITY_UPDATED: Attachment, Deployment, Execution, Group, IdentityLink, Job, Model, ProcessDefinition, ProcessInstance, Task, User.

    只有事件被发送,对应的引擎内的监听器才会被通知到。你有很多引擎 - 在同一个数据库运行 - 事件只会发送给注册到对应引擎的监听器。其他引擎发生的事件不会发送给这个监听器,无论实际上它们运行在同一个或不同的JVM中。

    对应的事件类型(对应实体)都包含对应的实体。根据类型或事件,这些实体不能再进行更新(比如,当实例以被删除)。可能的话,使用事件提供的 EngineServices 来以安全的方式来操作引擎。即使如此,你需要小心的对事件对应的实体进行更新/操作。