Activiti的全局事件机制及其监听处理
概述
Activiti在5.15以后的版本后,增加了统一的事件入口,不需要再像以前那样,监听流程的事件时,在流程定义的BPMN文件中为每个节点及流程增加以下的配置,以实现监听事件的做法,这种做法导致我们发布流程时,需要对bpmn文件进行设置,非常不方便,若调整其XML或Class类名或包名,都需要对BPMN文件重新修改并且发布,难度可想而知。
为了规避这种问题,我们重新引入统一监控机制,其思路来自Activiti的开发指导文件,如下:
http://www.activiti.org/userguide/index.html#eventDispatcherConfiguration
构建Activiti的事件分发器
统一事件处理,有利于为流程与业务的结合提供统一入口的处理,同进为后续的流程扩展提供了便利,包括任务人员的指派、会签的计算、流程回退的处理、流程日志等提供数据的切入口,所以通过构建我们的事件监听器就显得非常重要了。
定义的全局事件监听器的入口
package com.redxun.bpm.activiti.listener;
import java.util.HashMap;
import java.util.Map;
import org.activiti.engine.delegate.event.ActivitiEvent;
import org.activiti.engine.delegate.event.ActivitiEventListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.redxun.saweb.util.WebAppUtil;
/**
* Activiti的全局事件监听器,即所有事件均需要在这里统一分发处理
* @author csx
* @copyright http://www.redxun.cn
*
*/
public class GlobalEventListener implements ActivitiEventListener{
/**
* 日志处理器
*/
public final static Log logger=LogFactory.getLog(GlobalEventListener.class);
//事件及事件的处理器
//private Map<String,EventHandler> handlers=new HashMap<String, EventHandler>();
//更换为以下模式,可以防止Spring容器启动时,ProcessEngine尚未创建,而业务类中又使用了这个引用
private Map<String,String> handlers=new HashMap<String, String>();
@Override
public void onEvent(ActivitiEvent event) {
String eventType=event.getType().name();
logger.debug("envent type is ========>" + eventType);
//根据事件的类型ID,找到对应的事件处理器
String eventHandlerBeanId=handlers.get(eventType);
if(eventHandlerBeanId!=null){
EventHandler handler=(EventHandler)WebAppUtil.getBean(eventHandlerBeanId);
handler.handle(event);
}
}
@Override
public boolean isFailOnException() {
return false;
}
public Map<String, String> getHandlers() {
return handlers;
}
public void setHandlers(Map<String, String> handlers) {
this.handlers = handlers;
}
}
如何把全局监听加至Activiti的配置中去
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
<property name="dataSource" ref="dataSource" />
<property name="transactionManager" ref="transactionManager" />
<property name="databaseSchemaUpdate" value="true" />
<property name="jobExecutorActivate" value="false" />
<property name="enableDatabaseEventLogging" value="false" />
<property name="databaseType" value="${db.type}" />
<property name="idGenerator" ref="actIdGenerator"/>
<property name="eventListeners">
<list>
<ref bean="globalEventListener"/>
</list>
</property>
<property name="activityFontName" value="黑体"/>