一、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); }
結果輸出