您的位置:首页 > 其它

activiti学习笔记10--Event handlers--20170705

2017-07-05 15:04 447 查看
可以通过为一些特定的事件注册监听器达到监听事件触发的目的。注册监听器方式:1.通过配置添加;2.使用运行时API添加;3.BPMN
XML中添加。

所有事件都是org.activiti.engine.delegate.event.ActivitiEvent的子类。

1.事件监听实现

实现事件监听的唯一要求,是实现org.activiti.engine.delegate.event.ActivitiEventListener接口,举例:

打印所有接收到的事件,事件异常关联job-execution

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;
}
}


事件触发时执行onEvent(..)方法,当onEvent(..)方法中抛出异常时,执行isFailOnException()方法。若isFailOnException()方法返回
false
 ,忽视该异常,否则当前指令执行失败。如果事件是事务中的一部分,该事务回滚。如果事件监听中的行为不是业务关键,建议返回false

Activiti提供一些基础的接口实现来方便常用的事件监听,这些实现类也可以当做基类使用,如org.activiti.engine.delegate.event.BaseEntityEventListener。

2.配置中添加监听

流程引擎配置中添加的事件监听,在流程引擎启动时就激活,而且在会保持激活状态。

配置文件中既可使用内联bean,也可使用ref来关联已定义的bean。

2.1通过 
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>


2.2 监听指定类型事件,可使用
typedEventListeners
 ,配置该属性,需要一个使用逗号隔开的映射条目确定要监听的事件类型,监听器列表中的实例须实现
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
 ,再执行
typedEventListeners
 。

3.使用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);
注意:引擎重启后,使用RuntimeService添加的监听也失效。
4.流程定义中添加监听

可在特定的流程定义中添加监听。与流程定义相关的事件,以及与流程实例相关的所有事件,才会调用该类监听。这些事件都是与特定的流程定义一起启动的。


Listeners executing user-defined logic


下面代码片段中添加两个监听,第一个监听使用标准的类名,监听所有类型的事件;第二个使用表达式,通过已经
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>
事件关联实体,也可通过在流程定
c634
义中添加如下配置完成对特定实体类型的事件监听。支持的实体类型:
attachment
comment
execution
identity-link
job
process-instance
,
process-definition
task

<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>



Listeners throwing BPMN events

控制事件转发的另一种方式是抛出BPMN事件,但只有抛出特定工作流类型的BPMN事件才有意义。

<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事件,可通过继承工作流提供的监听类实现。通过重写子类中的isValidEvent(ActivitiEvent
event)
方法,可以阻止BPMN事件抛出。


Notes on listeners on a process-definition

1.事件监听器只能在process元素中定义,例如子元素extensionElements;监听器不能在流程的单个活动中定义;

2.
delegateExpression
 中的表达式不能访问执行上下文;该类表达式只能引用配置文件或者spring中实现监听接口的bean;

3.使用监听器类属性时,都是在创建时采用单例创建,须确保监听器实现不依赖于成员字段,或确保多线程/上下文的安全使用。

4.使用非法的事件属性或者非法的抛出事件,部署流程定义时会抛出异常,事件部署失败;非法的类或者
delegateExecution
 出现,会在流程启动时(或流程定义的第一个合法事件被处理时)抛出异常。须确保引用的类在classpath下且表达式可被处理为合法实例。

使用API处理事件

activiti通过API开放了事件处理机制,允许处理在引擎中注册的监听器事件。推荐使用RuntimeService只处理
ActivitiEvents
 中CUSTOM类型的事件。

/**
* 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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  activiti