前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >otto框架解析

otto框架解析

作者头像
haifeiWu
发布2018-09-11 10:25:54
3720
发布2018-09-11 10:25:54
举报

otto是square公司出的一个事件库(pub/sub模式),用来简化应用程序之间的通讯。

基本原理

框架中有两个注解(@Produce、@Subscribe),分别代表生产者,订阅者。在发布事件时,框架会通过识别方法是否含有@Subscribe以及参数来确定相应的方法,然后通过反射执行所有符合该事件的方法。

构造函数

Bus有5个构造函数,但最宗都会实现Bus(ThreadEnforcer enforcer, String identifier, HandlerFinder handlerFinder)构造方法,其中:

enforcer为Bus指定所在线程,可通过ThreadEnforcer.ANT或者ThreadEnforcer.MAIN来指定,默认为在主线程执行。

identifier相当与给Bus起一个名字,会在toString方法中使用。

handlerFinder是整个event bus的核心,不需要用户来指定,它用于在register、unregister的时候查找所有的Produce、Subscribe。默认的参数为HandlerFinder.ANNOTATED,也就是说HanlderFinder的具体实现类为AnnotatedHandlerFinder。

Bus使用时一般采用单例模式。

注册

如果一个类对某些事件感兴趣,则需要调用register方法来注册监听。

register会首先调用handlerFinder.findAllProducers(object)来找到所有使用了@Produce注解的方法。findAllProducers其实是委托AnnotatedHandlerFinder.findAllProducers方法。

在调用完findAllProducers方法之后,会遍历传入的监听类的Produce方法,并且根据Produce方法的返回类型,来检查是否有对应的Subscribe存在,如果有的话,就会调用Subscribe方法,并将Producer的返回值传入。

代码语言:javascript
复制
Map<Class<?>, EventProducer> foundProducers = handlerFinder.findAllProducers(object);
for (Class<?> type : foundProducers.ketSet() ) {
    final EventProducer producer = foundProducers.get(type);
    EventProducer previousProducer = producersByType.putIfAbsent(type, producer);
    ...
    Set<EventHandler> handlers = handlersByType.get(type);
    if (handlers != null && !handlers.isEmpty()) {
        for (EventHandler handler : handlers) {
            dispatchProducerResultToHandler(handler, producer);
        }
    }
}

这里需要注意的是,Bus对象两个Map类型的常量,用来缓存所有的Producer和Subscriber。

找到了所有的Producers之后,就是调用handlerFinder.findAllSubcribers(object)来寻找object中使用@Subscriber注解的方法,过程和findAllProducers类似,唯一不同的是一个事件中可以有多个Subscribe,却只能有一个Producer,根据他们的返回值类型可以判断。

找到监听类所有的subscribe方法自后,就需要查看Bus中有和这些subscribe对应的producer方法,如果有的话,就会立即调用subscribe方法。这也就是文档上说的,一但有新的subscribe订阅了某一事件,并且该事件有对应的producer,那么subscribe方法就会立即被调用,并且传入producer方法的返回值。

发送事件

post(Object event)方法用来发送事件给所有的订阅者。它接受的是一个Object类型,说明otto的事件可以是任意类型的对讲。

代码语言:javascript
复制
Set<Class<?>> dispatchTypes = flattenHierarchy(event.getClass());
for (Class<?> eventType :disPatchTypes) {
	...
}

post方法首先会获取所有event对象的父类,饭后遍历这些父类,找到他们所有的订阅者,发送事件,这表明任何订阅了event对象的订阅者也都会收到event事件。

值得注意的是Otto使用ThreadLocal类型来存放事件队列,这样极大的简化了多线程模式下的开发。

取消订阅

unregister方法做的事情和register刚好相反,从缓存中清除所有和当前监听对象相关的producers和subscribers。

作 者:ChanghuiN

原文链接:https://cloud.tencent.com/developer/article/1333357

版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基本原理
  • 构造函数
  • 注册
  • 发送事件
  • 取消订阅
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档