事件总线 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 阅读(16636) 评论(1) 编辑 收藏 举报