自定义的事件监听与处理框架。
如果只想监听到自已所关心的事件呢,那么就要自已实现一套事件处理的小框架了:
首先重新定义事件监听器接口,不再使用SPRING提供的ApplicationListener接口:
- import java.util.List;
- /**
- * 事件处理接口,实现此接口并且getEventClasses方法的返回结果条数大于0,方可处理对应的事件
- */
- public interface IBaseEventListener {
- /**
- * 事件处理的方法
- */
- public void onBaseEvent(BaseEvent event);
- /**
- * 所要处理的事件类型
- */
- public List<Class<? extends BaseEvent>> getEventClasses();
- }
这个接口比SPRING的事件接口多了一个方法。因为SPRING原来做法是只要实现了它提供的接口,任何事件发生时都会得到调用,这种做法是很方便使用的,这里沿用了这种思路。多出的那个方法作用是描述本类处理哪些事件。这时我需要一个类,这个类要在系统启动时把所有实现此接口的业务类找出来,归好类,以便事件发生时进行精确调用,并且提供事件发布事件的静态方法,这样我们才能知道事件在何时发生了。好,下面就来编写这个类
- /**
- * 事件处理相关操作工具类
- */
- public class EventController {
- /** KEY:事件类的类名,值:所有监听此事件的处理类实例 */
- private static Map<String,List<IBaseEventListener>> listeners = new LinkedHashMap<String, List<IBaseEventListener>>();
- private EventController(){
- //no instance
- }
- /**
- * 扫瞄所有bean,进行事件监听(业务类按事件类型归类),此方法要在系统启动完后立即调用
- * 此方法大概过程是
- * 1、从SPRING中找出所实现了IBaseEventListener的具体业务类实例
- * 2、把这些实例归类装进MAP变量listeners中,此MAP变量的结构是:
- * "UserDeleteEvent.class",{ortherServiceImpl,xxxServiceImpl,...}
- * "UserUpdateEvent.class",{yyyServiceImpl,zzzServiceImpl,...}
- * key,valueList
- */
- public static void initBaseEventListener(){
- //从SPRING中得到实现了某接口的业务类
- Map<String,IBaseEventListener> beans = ContextLoader.getCurrentWebApplicationContext().getBeansOfType(IBaseEventListener.class);
- if(beans==null || beans.size()==0)
- return;
- //下面循环进行归类
- Collection<IBaseEventListener> services = beans.values();
- for (IBaseEventListener service : services) {
- List<Class<? extends BaseEvent>> eventClasses = service.getEventClasses();
- if(eventClasses==null || eventClasses.size()==0)
- continue;
- for (int i = 0; i < eventClasses.size(); i++) {
- List<IBaseEventListener> list = listeners.get(eventClasses.get(i).getName());
- if(list==null){
- list = new ArrayList<IBaseEventListener>();
- listeners.put(eventClasses.get(i).getName(), list);
- list.add(service);
- }else{
- if(list.contains(service)){
- continue;
- }else{
- list.add(service);
- }
- }
- }
- }
- }
- /**
- * 发布事件的静态方法
- */
- public static void publishEvent(BaseEvent event){
- //根据实际事件名称,从listeners中找出监听了此事件的业务类,调用之
- List<IBaseEventListener> list = listeners.get(event.getClass().getName());
- if(list!=null && list.size()>0){
- for (IBaseEventListener listener : list) {
- //此处不能捕捉异常,因为任何一个处理类实例出错都应该全部回滚
- listener.onBaseEvent(event);
- }
- }
- }
- }
接着重新定义事件类本身,此类也不再继承SPRING的ApplicationEvent类,其它基本还和原来一样。
- public class BaseEvent {
- private Object source;
- public BaseEvent() {
- }
- public BaseEvent(Object source) {
- this.source = source;
- }
- public Object getSource() {
- return source;
- }
- }
业务类顶层接改而继承自已的事件接口
- /**
- * 业务层顶层接口
- */
- public interface IBaseService extends IBaseEventListener{
- }