事件总线Guava EventBus
一、EventBus概述
Guava 事件总线EventBus允许在服务内部的组件之间进行发布-订阅式的通信,是观察者模式的优雅实现。观察者模式和EventBus都需要注册监听者事件,发布者发布事件。
不同在于观察者模式的发布者需要继承Observable,实现事件发布的逻辑,监听者需要自己实现Observer接口,而EventBus只需要在事件总线上发布事件,注册监听者,同时监听者的监听方法上添加@Subscribe注解即可。
二、EventBus实现
如下以老师发布作业到事件总线上,注册学生的监听者,监听者接收到作业后触发下一步动作为例,讲解EventBus的实现。
事件定义:发布者支持发布对象类型的事件,也支持发布基本数据类型的消息,定义如下:
/** * 发布作业的事件 * @author test11 */ public class WorkEvent { private String message; public WorkEvent(String message) { this.message = message; } public String getMessage() { return message; } }
Subscriber(订阅者)定义:使用Guava之后发布-订阅模式就变得很简单了,如果你需要订阅某种类型的消息,只需要在指定的方法上加上@Subscribe注解即可
1、一个Subscriber也可以同时订阅多个事件,Guava会通过事件类型来和订阅方法的形参来决定到底调用subscriber的哪个订阅方法
2、多个subscriber订阅了同一个事件,那么每个subscriber都将收到事件通知,并且收到事件通知的顺序跟注册的顺序保持一致
/** * 学生1订阅事件 * @author test11 */ public class Stu1Listener { @Subscribe public void listen(WorkEvent event) { System.out.println("学生1接收事件:" + event.getMessage()); } @Subscribe public void listen(String event) { System.out.println("学生1接收字符串消息:" + event); } }
import com.google.common.eventbus.Subscribe; /** * 学生2订阅事件 * @author test11 */ public class Stu2Listener { @Subscribe public void listen(WorkEvent event) { System.out.println("学生2接收事件:" + event.getMessage()); } @Subscribe public void listen(String event) { System.out.println("学生2接收字符串消息:" + event); } @Subscribe public void listen(Integer event) { System.out.println("学生2接收Integer:" + event); } }
EventBus事件注册:
1、Stu1Listener和Stu2Listener都订阅了WorkEvent事件,所以他们都会收到WorkEvent事件通知。但是Stu1Listener会第一个收到WorkEvent 事件通知,其次是Stu2Listener
2、Stu1Listener没有订阅整数类型的接收,所以不会受到整数类型的通知
/** * @author test11 */ public class Demo { public static void main(String[] args) { //创建EventBus对象和名称,此场景为老师布置作业后触发学生们的响应 EventBus teacherBus = new EventBus("work"); //注册所有的订阅者,此处主要是注册监听的学生对象 teacherBus.register(new Stu1Listener()); teacherBus.register(new Stu2Listener()); //发布布置作业事件 teacherBus.post(new WorkEvent("默写2遍课文")); teacherBus.post(new WorkEvent("背诵100个单词")); teacherBus.post("默写2遍课文"); teacherBus.post("背诵100个单词"); teacherBus.post(2); teacherBus.post(100); }
结果输出