动手实现一个EventBus
文章目录
一、说明
在Guava中,EventBus简化了观察者模式的实现。理解EventBus的原理来,自动动手实现一个简单的EventBus。
二、Guava的EventBus
EventBus叫做“时间总线”,它提供了实现观察者模式的骨架代码。可以基于此框架,非常容易地在自己的业务场景中实现观察者模式。它不仅支持异步非阻塞模式,同时支持同步阻塞模式。
基于EventBus,不需要定义Observer接口(观察者接口),任意类型的对象都可以注册到EventBus中。通过@Subscribe
注解来表明类中哪个函数可以接收观察者发送的消息。
Guava EventBus中的几个主要的类和函数:
-
EventBus、SyncEventBus
EventBus类中封装了对外暴露的所有可调用接口。其中EventBus实现了同步阻塞的观察者模式,SyncEventBus继承EventBus提供了异步非阻塞的观察者模式。
// 同步阻塞的方式 EventBus eventBus = new EventBus(); // 异步非阻塞的方式 final int DEFAULT_EVENTBUS_THREAD_POOL_SIZE = 20; // 异步非阻塞线程池大小 ExecutorService executorService = Executors.newFixedThreadPool(DEFAULT_EVENTBUS_THREAD_POOL_SIZE); EventBus eventBus = new AsyncEventBus(executorService);
-
register()
函数EventBus通过
register()
函数来注册观察者。它可以接收任意类型(Object)的观察者。具体的函数定义如下:public void register(Object object) { //...... }
-
unregister()
函数相对于
register()
,unregister()
函数是从EventBus中删除某个观察者。public void unregister(Object object) { //...... }
-
post
函数EventBus提供
post()
函数 ,用来给观察者发消息。public void post(Object event) { //...... }
post发送消息的时候,并不是把消息发送给所有的观察者,而是发送给可匹配的观察者。所谓可匹配指的是,能接收的消息类型是发送消息(post函数中定义的父类)。
比如,AObserver能接收的消息类型是XMsg,BObserver能接收的消息类型是YMsg,CObserver能接收的消息类型是ZMsg。其中,XMsg是YMsg的父类。
XMsg xMsg= new XMsg(); YMsg yMsg= new YMsg(); ZMsg zMsg= new ZMsg(); post(xMsg);// AObserver 接收消息 post(yMsg);// AObserver和BObserver接收到消息 post(zMsg);// CObserver接收到消息
Observer(观察者)能接收到消息类型是通过
@Subscribe
注解定义的。 -
@Subscribe
注解EventBus通过
@Subscribe
注解类标明,某个函数能接收哪种类型的消息。(类型不能是基本类型)
三、EventBus的原理
四、动手实现一个EventBus
@Beat
标注一个公共的API(公共的类、方法或字段) 在未来的发行版本中会发生不兼容的变化。带有此注释的 API 不受其包含库所做的任何兼容性保证。请注意,此注释的存在并不意味着所讨论 API 的质量或性能,只是它不是“API 冻结”的事实。
应用程序依赖 beta API 通常是安全的,但需要在升级期间进行一些额外的工作。然而,不建议在类库(包含在用户的CLASSPATH中,不受开发人员的控制)上这么做。
4.1 定义Subscribe注解
定义Subscribe注解,用于标明哪个函数可以接收消息。
/**
* 定义一个注解,表明观察者中的哪个函数可以接收消息
*/
@Retention(RetentionPolicy.RUNTIME) // 注解的声明周期
@Target(ElementType.METHOD) // 注解作用的地方
@Beta // 标注API在未来发行的版本是可能有不兼容的变化
public @interface MySubscribe {
}
4.2 ObserverAction
用来表示@MySubscribe
注解的方法。
/**
* 用来表示 @MySubscribe 注解方法
* @Date 2022/10/23
* @Author lifei
*/
public class