事件总线 EventBus的设计

  为什么要设计EventBus,因为他是领域驱动设计中比不可少的模块,它承担传输数据的作用,它可以解耦模块之间的耦合性。

  如何对EventsBus进行定义。1、EventBus是基于JVM内部的数据传输系统,不是JMS;EventBus的核心对象为Event和EventHandler。

  

  EventBus的模块结构如下:

  EventService对外提供各种服务,它依赖queue,bus,annotatin。

  queue包为EventService提供事件源。

  bus包提供两种事件总线:ClassEventBus和TopicEventBus。

  annotatin包提供两种注解方式@ClassEventHandler和@TopicEventHandler。

 

  queue包结构如下:

  QueueWrapper是对各种Event的包装,使他们能够统一放入Queue。

  EventQueue本质上阻塞队列,负责接收事件和提取事件。

  

  Bus包结构如下:

  EventBus是Facade类,统筹ClassEventBus和TopicEventBus,ClassEventBus和TopicEventBus在处理订阅着、分发事件是相似的,区别在Class是针对事件的类型,而TopicEventBus针对的主题。以ClassEventBus的为例,结构如下:

  Key2List是 是对 Map<key,List<Value>> 中List<Value>的封装,统一各种常用的操作,EventType2Event是个事件类型对应的事件列表,用于缓存控制。Class2Handler保存事件的订阅者,ClassEventBus每发布一次事件,都会Class2Handler中取得订阅者。

  notifyHandlers(Event)是Bus一个关键设计点。如果是采用一个线程循环处理所有事件的方式,在处理复杂计算的事情时,会影响其他订阅者。如果是采用每个线程对应一个订阅者,则在高并发的情况下,线程会增加,系统资源占用率提高。如果是采用Executor来应对,则是折中的办法。

  订阅者想处理ClassEvent,必须实现ClassEventHandler。

 

  annotation包是以注解的方式来调用bus包下各种EventBus。如果想让业务Facade类,监听某个事件,则给方法加上@ClassEventHandler或@TopicEventHandler。然后让AnnotationProcessor调用process即可。以ClassEventHandler对应的模块为例,来介绍其结构:

  AnnotationProcessor的process处理过程如下:
      1、从object对象,找出带有ClassEventHanlder的函数。
      2、把方法和Object,整合到ProxClassHandler。
      3、ProxyClassHanlder注册到EventService中。

  ProxyClassHandler最重要的边上onEvent(Evenet),它的功能是以反射的方式调用指定方法。

 

 

  最后是介绍EventService,它的结构很简单:

  其中,最关键的时RunTask,他继承Runnable类,在run()中,线程不停地从eventQueue获取事件,然后发布给订阅者。当然RunTask在EventService初始化的时候,就会生成,知道EventService销毁。

 

  以上就是事件总线的设计思路,如有好的想法,请与我交流,最后附上一张最终的类图。

posted on 2011-12-21 22:50  small.ming  阅读(16626)  评论(1编辑  收藏  举报

导航