转载

Guava之EventBus使用总结

1.将EventBus封装为单例模式使用

  1 package priv.jack.demo.listener;  2   3 import java.util.Map;  4   5 import com.google.common.collect.Maps;  6 import com.google.common.eventbus.EventBus; 8   9 /** 10  * 事件总线工厂 11  * 将EventBus封装为单例模式使用 12  * @author Jack 13  * 14  */ 15 public class EventBusFactory { 16      17     private volatile static EventBusFactory  INSTANCE ; 18      19     /** 20      * 保存已经注册的监听器,防止监听器重复注册 21      */ 22     private Map<String, Class<? extends EventListener>> registerListenerContainers = Maps.newConcurrentMap() ; 23      24     private EventBusFactory() {} 25      26     public static EventBusFactory build() { 27         if(INSTANCE == null) { 28             synchronized (EventBusFactory.class) { 29                 if(INSTANCE == null) { 30                     INSTANCE = new EventBusFactory() ; 31                 } 32             } 33         } 34         return INSTANCE ; 35     } 36      37     private final EventBus EVENTBUS = new EventBus() ; 38      39     /** 40      * 事件转发 41      * @param event 42      */ 43     public void postsEvent(SystemEvent event) { 44         EVENTBUS.post(event) ; 45     } 46      47     /** 48      * 监听器注册 49      * @param clazz 50      */ 51     public void register(Class<? extends EventListener> clazz)  { 52         String clazzName = clazz.getSimpleName() ; 53         if(registerListenerContainers.containsKey(clazzName)) { 54             return ; 55         } 56         try { 57             registerListenerContainers.put(clazzName, clazz) ; 58             Object obj = registerListenerContainers.get(clazzName).newInstance(); 59             EVENTBUS.register(obj) ; 60         } catch (Exception e) { 61             e.printStackTrace(); 62         }  63     } 64 } 

封装之后,将EventBus的post和register也进行封装

2.封装SystemEvent作为事件的顶层父类,为了使EventBusFactory的postEvent更通用

 package priv.jack.demo.listener.event;  /**  * 系统事件父类  * @author Jack  *  */ public class SystemEvent {          public static final String MEMBER_DELETE_EVENT = "memberDelEvt" ;     public static final String TEST_EVENT = "testEvt" ;      private String eventName;          public SystemEvent() {              }          public SystemEvent(String eventName) {         this.eventName = eventName;     }          @Override     public String toString() {         return "SystemEvent [eventName=" + eventName + "]";     }        public String getEventName() {         return eventName;     }      public void setEventName(String eventName) {         this.eventName = eventName;     } } 

3.编写事件子类

 package priv.jack.demo.listener.event;  public class TestEvent extends SystemEvent {      private String testField;      public String getTestField() {         return testField;     }      public void setTestField(String testField) {         this.testField = testField;     }          public TestEvent() {}          public TestEvent(String eventName, String testField) {         super(eventName) ;         this.testField = testField ;     }  }  package priv.jack.demo.listener.event;  import java.util.List;  /**  * 成员删除事件  * 该事件触发画面合成修改操作  * @author Jack  *  */ public class MemberDeletedEvent extends SystemEvent{      private String confCreatorToken;      private List<String> e164ListToOper ;      private int cmd;          public MemberDeletedEvent() {     }          public MemberDeletedEvent(String eventName) {         super(eventName);     }          public MemberDeletedEvent(String eventName, String confCreatorToken, List<String> e164ListToOper, int cmd) {         this(eventName) ;         this.confCreatorToken = confCreatorToken ;         this.e164ListToOper = e164ListToOper ;         this.cmd = cmd ;     }      @Override     public String toString() {         return "MemberDeletedEvent [confCreatorToken=" + confCreatorToken + ", e164ListToOper=" + e164ListToOper + ", cmd=" + cmd + "]";     }      public String getConfCreatorToken() {         return confCreatorToken;     }      public void setConfCreatorToken(String confCreatorToken) {         this.confCreatorToken = confCreatorToken;     }      public List<String> getE164ListToOper() {         return e164ListToOper;     }      public void setE164ListToOper(List<String> e164ListToOper) {         this.e164ListToOper = e164ListToOper;     }      public int getCmd() {         return cmd;     }      public void setCmd(int cmd) {         this.cmd = cmd;     }  } 

4.编写Listener接口类

 public interface EventListener {      public void action(SystemEvent event) ;      } 

5.编写Listener实现类

 /**  * 测试事件监听类  * @author Jack  *  */ public class TestEventListener implements EventListener{          private Logger logger = LoggerFactory.getLogger("birdie") ;      @Override     @Subscribe     @AllowConcurrentEvents     public void action(SystemEvent event) {         logger.info(String.format("[TestEventListener ] action, listener=%s event=%s", this.toString(), event.toString()));         TestEvent subEvent = (TestEvent) event ;         invoke(subEvent) ;     }          public void invoke(TestEvent testEvent) {         logger.info(String.format("[TestEventListener ] action testEvent=%s", testEvent.toString()));     }  }   /**  * 成员删除事件监听器, 支持并发操作  * @see MemberDeletedEvent  * @see birdie-web下的EventBusTest  * @author Jack  *  */ public class MemberDeletedEventListener implements EventListener{          private Logger logger = LoggerFactory.getLogger("birdie") ;      @Override     @Subscribe     @AllowConcurrentEvents     public void action(SystemEvent event) {         logger.info(String.format("[MemberDeletedEventListener ] action event=%s", event.toString()));         MemberDeletedEvent subEvent = (MemberDeletedEvent) event ;         invoke(subEvent) ;     }          public void invoke(MemberDeletedEvent memberDeletedEvent) {         if(MtsOper.MT_DELETE.getOperCode() == memberDeletedEvent.getCmd()) {             //...业务代码         }     }  } 

6.单元测试

 public class EventBusTest {          //测试重复注册监听器     @Test     public void testRepeatRegister() {         final EventBus bus = new EventBus() ;         bus.register(new TestEventListener());         bus.register(new TestEventListener());                  TestEvent event = new TestEvent(SystemEvent.TEST_EVENT, "123") ;         bus.post(event);     }          //测试并发操作     //@Test     public void testConcurrcy() {         List<String> list = Lists.newArrayList("001#01") ;         MemberDeletedEvent event = new MemberDeletedEvent(SystemEvent.MEMBER_DELETE_EVENT, "123", list , 1) ;         for(int i=0 ; i < 100 ; i++) {             final int cnt = i ;             Thread t = new Thread(new Runnable() {                 @Override                 public void run() {                     try {                         Thread.sleep(3000);                     } catch (InterruptedException e) {                         e.printStackTrace();                     }                      System.out.println("第"+ cnt+ "次");                     EventBusFactory.build().register(MemberDeletedEventListener.class) ;                 }             }) ;             t.start();          }         try {             Thread.sleep(6000);         } catch (InterruptedException e) {             e.printStackTrace();         }          EventBusFactory.build().postsEvent(event);     }      //测试继承结构下的事件分发     @Test     public void testInherit() {         TestEvent event = new TestEvent(SystemEvent.TEST_EVENT, "123") ;         EventBusFactory.build().register(TestEventListener.class) ;         EventBusFactory.build().postsEvent(event);     } } 

总结

1.支持类的继承结构下的事件分发,但子类和父类都能收到事件。

2.@AllowConcurrentEvents 进行并发设置,经过简单测试是OK的

相关问题

1.如何能够很优雅的进行对监听器进行集中且动态的注册,让其可扩展性更好

目前上面demo的代码是在post之前进行register,并在register中进行重复注册的屏蔽, 如果新增监听器的话需要修改代码,可扩展性差

2.请大牛对代码进行评价

原文  http://www.cnblogs.com/jack2013/p/5162838.html
正文到此结束
Loading...