zoukankan      html  css  js  c++  java
  • 事件处理程序

    Activiti引擎中的事件机制允许您在引擎内发生各种事件时得到通知。查看所有支持的事件类型以了解可用事件的概述。

    注册侦听器的3种方式:

    所有派发出去的事件都是org.activiti.engine.delegate.event.ActivitiEvent的一个子类该事件暴露了(如果有的话)typeexecutionIdprocessInstanceIdprocessDefinitionId某些事件包含与发生的事件相关的附加上下文,可在所有支持的事件类型列表中找到有关附加内容的附加信息

    实现事件监听器

    事件监听器的唯一要求是实现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 支持的类型包括:attachmentcommentexecutionidentity-linkjobprocess-instanceprocess-definitiontask.

    处理被分派事件的另一种方式是抛出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.SignalThrowingEventListenerTestorg.activiti.engine.impl.bpmn.helper.MessageThrowingEventListenerorg.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

    表1.支持的事件
    活动名称描述事件类

    ENGINE_CREATED

    这个监听器所连接的流程引擎已经被创建并准备好接受API调用。

    org.activiti…​ActivitiEvent

    ENGINE_CLOSED

    这个监听器所附的进程引擎已关闭。对引擎的API调用不再可能。

    org.activiti…​ActivitiEvent

    ENTITY_CREATED

    一个新的实体被创建。新的实体包含在事件中。

    org.activiti…​ActivitiEntityEvent

    ENTITY_INITIALIZED

    一个新的实体已经创建并完全初始化。如果任何儿童是作为创建实体的一部分而创建的,则此事件将在创建/初始化子实体之后被触发,而不是ENTITY_CREATE事件。

    org.activiti…​ActivitiEntityEvent

    ENTITY_UPDATED

    现有更新。更新的实体包含在事件中。

    org.activiti…​ActivitiEntityEvent

    ENTITY_DELETED

    现有的实体被删除。被删除的实体包含在事件中。

    org.activiti…​ActivitiEntityEvent

    ENTITY_SUSPENDED

    现有的实体已被暂停。暂停的实体包含在事件中。将派发ProcessDefinitions,ProcessInstances和Tasks。

    org.activiti…​ActivitiEntityEvent

    ENTITY_ACTIVATED

    现有实体已激活。激活的实体包含在事件中。将派发ProcessDefinitions,ProcessInstances和Tasks。

    org.activiti…​ActivitiEntityEvent

    JOB_EXECUTION_SUCCESS

    作业已成功执行。该事件包含已执行的作业。

    org.activiti…​ActivitiEntityEvent

    JOB_EXECUTION_FAILURE

    作业的执行失败。该事件包含已执行的作业和异常。

    org.activiti…​ActivitiEntityEvent 和 org.activiti…​ActivitiExceptionEvent

    JOB_RETRIES_DECREMENTED

    由于作业失败,作业重试次数已减少。该事件包含已更新的作业。

    org.activiti…​ActivitiEntityEvent

    TIMER_FIRED

    计时器已被解雇。该事件包含已执行的作业?

    org.activiti…​ActivitiEntityEvent

    JOB_CANCELED

    工作已被取消。该事件包含被取消的作业。在新的流程定义部署中,可以通过API调用取消作业,完成任务并取消关联的边界计时器。

    org.activiti…​ActivitiEntityEvent

    ACTIVITY_STARTED

    活动正在开始执行

    org.activiti…​ActivitiActivityEvent

    ACTIVITY_COMPLETED

    活动已成功完成

    org.activiti…​ActivitiActivityEvent

    ACTIVITY_CANCELLED

    一项活动将被取消。活动取消有三个原因(MessageEventSubscriptionEntity,SignalEventSubscriptionEntity,TimerEntity)。

    org.activiti…​ActivitiActivityCancelledEvent

    ACTIVITY_SIGNALED

    活动收到信号

    org.activiti…​ActivitiSignalEvent

    ACTIVITY_MESSAGE_RECEIVED

    活动收到消息。在活动收到消息之前分派。收到后,将根据类型(边界事件或事件子流程启动事件)为此活动分派ACTIVITY_SIGNALACTIVITY_STARTED将被分派,

    org.activiti…​ActivitiMessageEvent

    ACTIVITY_ERROR_RECEIVED

    活动已收到错误事件。在活动处理实际错误之前分派。该事件activityId包含对错误处理活动的引用。 如果错误已成功传递,则该事件将随后是ACTIVITY_SIGNALLED事件或ACTIVITY_COMPLETE涉及的活动。

    org.activiti…​ActivitiErrorEvent

    UNCAUGHT_BPMN_ERROR

    未捕获的BPMN错误已被抛出。该过程没有针对该特定错误的任何处理程序。该事件activityId将是空的。

    org.activiti…​ActivitiErrorEvent

    ACTIVITY_COMPENSATE

    一项活动即将得到补偿。该事件包含将被执行以进行补偿的活动的ID。

    org.activiti…​ActivitiActivityEvent

    VARIABLE_CREATED

    一个变量已经创建。该事件包含变量名称,值和相关的执行和任务(如果有的话)。

    org.activiti…​ActivitiVariableEvent

    VARIABLE_UPDATED

    现有变量已更新。该事件包含变量名称,更新的值以及相关的执行和任务(如果有的话)。

    org.activiti…​ActivitiVariableEvent

    VARIABLE_DELETED

    现有的变量已被删除。该事件包含变量名称,最后一个已知值以及相关的执行和任务(如果有的话)。

    org.activiti…​ActivitiVariableEvent

    TASK_ASSIGNED

    任务已分配给用户。该事件包含该任务

    org.activiti…​ActivitiEntityEvent

    TASK_CREATED

    一项任务已经创建。这是在ENTITY_CREATE事件发生后发出的如果任务是进程的一部分,则在执行任务侦听器之前将触发此事件。

    org.activiti…​ActivitiEntityEvent

    TASK_COMPLETED

    一项任务已经完成。这是在ENTITY_DELETE事件发生之前发出的如果任务是流程的一部分,则该流程将在流程开始前被触发,并将在事件之后触发一个ACTIVITY_COMPLETE事件,针对表示已完成任务的活动。

    org.activiti…​ActivitiEntityEvent

    PROCESS_COMPLETED

    一个过程已经完成。在最后一个活动ACTIVITY_COMPLETED 事件之后分派当流程实例没有任何要转换的状态时,流程完成。

    org.activiti…​ActivitiEntityEvent

    PROCESS_CANCELLED

    一个进程已被取消。在从运行时删除流程实例之前调度。流程实例被API调用取消RuntimeService.deleteProcessInstance

    org.activiti…​ActivitiCancelledEvent

    MEMBERSHIP_CREATED

    用户已被添加到组中。该事件包含涉及的用户和组的ID。

    org.activiti…​ActivitiMembershipEvent

    MEMBERSHIP_DELETED

    用户已从组中删除。该事件包含涉及的用户和组的ID。

    org.activiti…​ActivitiMembershipEvent

    MEMBERSHIPS_DELETED

    所有成员将从组中删除。这个事件在成员被移除之前抛出,所以他们仍然可以访问。MEMBERSHIP_DELETED出于性能原因,如果所有成员一次被删除,则不会抛出任何个人 事件。

    org.activiti…​ActivitiMembershipEvent

    所有ENTITY_*事件都与实体相关。下面的列表显示了为哪些实体分派哪些实体事件的概述:

    • ENTITY_CREATED, ENTITY_INITIALIZED, ENTITY_DELETED:附件,评论,部署,执行,组,IdentityLink,作业,模型,ProcessDefinition,ProcessInstance,任务,用户。

    • ENTITY_UPDATED:附件,部署,执行,组,IdentityLink,作业,模型,ProcessDefinition,ProcessInstance,任务,用户。

    • ENTITY_SUSPENDED, ENTITY_ACTIVATED:ProcessDefinition,ProcessInstance / Execution,任务。

  • 相关阅读:
    测试框架 MSTest V2与单元测试
    string字符串格式
    重构概述
    代码的坏味道
    this.Dispatcher.Invoke与SynchronizationContext
    C# new关键字
    Servlet的API和生命周期
    Servlet快速入门
    Spring介绍
    Oracle数据安全解决方案(1)——透明数据加密TDE
  • 原文地址:https://www.cnblogs.com/jimboi/p/8470134.html
Copyright © 2011-2022 走看看