java guava eventbus_Guava之EventBus使用总结

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

1 packagepriv.jack.demo.listener;2

3 importjava.util.Map;4

5 importcom.google.common.collect.Maps;6 importcom.google.common.eventbus.EventBus;8

9 /**

10 * 事件总线工厂11 * 将EventBus封装为单例模式使用12 *@authorJack13 *14 */

15 public classEventBusFactory {16

17 private volatile staticEventBusFactory INSTANCE ;18

19 /**

20 * 保存已经注册的监听器,防止监听器重复注册21 */

22 private Map> registerListenerContainers =Maps.newConcurrentMap() ;23

24 privateEventBusFactory() {}25

26 public staticEventBusFactory build() {27 if(INSTANCE == null) {28 synchronized (EventBusFactory.class) {29 if(INSTANCE == null) {30 INSTANCE = newEventBusFactory() ;31 }32 }33 }34 returnINSTANCE ;35 }36

37 private final EventBus EVENTBUS = newEventBus() ;38

39 /**

40 * 事件转发41 *@paramevent42 */

43 public voidpostsEvent(SystemEvent event) {44 EVENTBUS.post(event) ;45 }46

47 /**

48 * 监听器注册49 *@paramclazz50 */

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更通用

packagepriv.jack.demo.listener.event;/*** 系统事件父类

*@authorJack

**/

public classSystemEvent {public static final String MEMBER_DELETE_EVENT = "memberDelEvt";public static final String TEST_EVENT = "testEvt";privateString eventName;publicSystemEvent() {

}publicSystemEvent(String eventName) {this.eventName =eventName;

}

@OverridepublicString toString() {return "SystemEvent [eventName=" + eventName + "]";

}publicString getEventName() {returneventName;

}public voidsetEventName(String eventName) {this.eventName =eventName;

}

}

3.编写事件子类

packagepriv.jack.demo.listener.event;public class TestEvent extendsSystemEvent {privateString testField;publicString getTestField() {returntestField;

}public voidsetTestField(String testField) {this.testField =testField;

}publicTestEvent() {}publicTestEvent(String eventName, String testField) {super(eventName) ;this.testField =testField ;

}

}packagepriv.jack.demo.listener.event;importjava.util.List;/*** 成员删除事件

* 该事件触发画面合成修改操作

*@authorJack

**/

public class MemberDeletedEvent extendsSystemEvent{privateString confCreatorToken;private Liste164ListToOper ;private intcmd;publicMemberDeletedEvent() {

}publicMemberDeletedEvent(String eventName) {super(eventName);

}public MemberDeletedEvent(String eventName, String confCreatorToken, List e164ListToOper, intcmd) {this(eventName) ;this.confCreatorToken =confCreatorToken ;this.e164ListToOper =e164ListToOper ;this.cmd =cmd ;

}

@OverridepublicString toString() {return "MemberDeletedEvent [confCreatorToken=" + confCreatorToken + ", e164ListToOper=" + e164ListToOper + ", cmd=" + cmd + "]";

}publicString getConfCreatorToken() {returnconfCreatorToken;

}public voidsetConfCreatorToken(String confCreatorToken) {this.confCreatorToken =confCreatorToken;

}public ListgetE164ListToOper() {returne164ListToOper;

}public void setE164ListToOper(Liste164ListToOper) {this.e164ListToOper =e164ListToOper;

}public intgetCmd() {returncmd;

}public void setCmd(intcmd) {this.cmd =cmd;

}

}

4.编写Listener接口类

public interfaceEventListener {public voidaction(SystemEvent event) ;

}

5.编写Listener实现类

/*** 测试事件监听类

*@authorJack

**/

public class TestEventListener implementsEventListener{private Logger logger = LoggerFactory.getLogger("birdie") ;

@Override

@Subscribe

@AllowConcurrentEventspublic voidaction(SystemEvent event) {

logger.info(String.format("[TestEventListener ] action, listener=%s event=%s", this.toString(), event.toString()));

TestEvent subEvent=(TestEvent) event ;

invoke(subEvent) ;

}public voidinvoke(TestEvent testEvent) {

logger.info(String.format("[TestEventListener ] action testEvent=%s", testEvent.toString()));

}

}/*** 成员删除事件监听器, 支持并发操作

*@seeMemberDeletedEvent

*@seebirdie-web下的EventBusTest

*@authorJack

**/

public class MemberDeletedEventListener implementsEventListener{private Logger logger = LoggerFactory.getLogger("birdie") ;

@Override

@Subscribe

@AllowConcurrentEventspublic voidaction(SystemEvent event) {

logger.info(String.format("[MemberDeletedEventListener ] action event=%s", event.toString()));

MemberDeletedEvent subEvent=(MemberDeletedEvent) event ;

invoke(subEvent) ;

}public voidinvoke(MemberDeletedEvent memberDeletedEvent) {if(MtsOper.MT_DELETE.getOperCode() ==memberDeletedEvent.getCmd()) {

//...业务代码}

}

}

6.单元测试

public classEventBusTest {

//测试重复注册监听器

@Testpublic voidtestRepeatRegister() {final EventBus bus = newEventBus() ;

bus.register(newTestEventListener());

bus.register(newTestEventListener());

TestEvent event= new TestEvent(SystemEvent.TEST_EVENT, "123") ;

bus.post(event);

}

//测试并发操作//@Test

public voidtestConcurrcy() {

List 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(newRunnable() {

@Overridepublic voidrun() {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);

}

//测试继承结构下的事件分发

@Testpublic voidtestInherit() {

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.请大牛对代码进行评价

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值