EventBus是Google.Guava提供的消息發(fā)布-訂閱類庫,它實現(xiàn)了觀察者設(shè)計模式,消息通知負(fù)責(zé)人通過EventBus去注冊/注銷觀察者,最后由消息通知負(fù)責(zé)人給觀察者發(fā)布消息。
1. 首先使用 maven 依賴:
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency>
2. 示例代碼:
2.1 注冊中心代碼 EventBusCenter.java
package com.lance.google.event.bus;
import com.google.common.eventbus.EventBus;
/**
* Created by lance on 2017/1/10.
*/
public class EventBusCenter {
private static EventBus eventBus = new EventBus();
private EventBusCenter() {
}
public static EventBus getInstance() {
return eventBus;
}
public static void register(Object obj) {
eventBus.register(obj);
}
public static void unregister(Object obj) {
eventBus.unregister(obj);
}
public static void post(Object obj) {
eventBus.post(obj);
}
}
2.2 觀察者一的代碼 DataObserver1.java
package com.lance.google.event.bus;
import com.google.common.eventbus.Subscribe;
/**
* Created by lance on 2017/1/10.
*/
public class DataObserver1 {
/**
* 只有通過@Subscribe注解的方法才會被注冊進EventBus
* 而且方法有且只能有1個參數(shù)
*
* @param msg
*/
@Subscribe
public void func(String msg) {
System.out.println("String msg: " + msg);
}
}
2.3 觀察者一的代碼 DataObserver2.java
package com.lance.google.event.bus;
import com.google.common.eventbus.Subscribe;
/**
* Created by lance on 2017/1/10.
*/
public class DataObserver2 {
/**
* post() 不支持自動裝箱功能,只能使用Integer,不能使用int,否則handlersByType的Class會是int而不是Intege
* 而傳入的int msg參數(shù)在post(int msg)的時候會被包裝成Integer,導(dǎo)致無法匹配到
*/
@Subscribe
public void func(Integer msg) {
System.out.println("Integer msg: " + msg);
}
}
2.4 代碼測試 Test.java
package com.lance.google.event.bus;
/**
* Created by lance on 2017/1/10.
*/
public class Test {
public static void main(String[] args) throws InterruptedException {
DataObserver1 observer1 = new DataObserver1();
DataObserver2 observer2 = new DataObserver2();
EventBusCenter.register(observer1);
EventBusCenter.register(observer2);
System.out.println("============ start ====================");
// 只有注冊的參數(shù)類型為String的方法會被調(diào)用
EventBusCenter.post("post string method");
EventBusCenter.post(123);
System.out.println("============ after unregister ============");
// 注銷observer2
EventBusCenter.unregister(observer2);
EventBusCenter.post("post string method");
EventBusCenter.post(123);
System.out.println("============ end =============");
}
}
2.5 輸出結(jié)果:
============ start ====================
String msg: post string method
Integer msg: 123
============ after unregister ============
String msg: post string method
============ end =============
看,使用起來簡單吧!
EventBus的使用注意問題:
1.代碼可讀性很差,項目中使用的時候,從post的地方,查詢handle使用,都是使用ide的搜索服務(wù),問題很難定位,不如普通的接口調(diào)用方便查詢;
2.由于EventBus是將消息隊列放入到內(nèi)存中的,listener消費這個消息隊列,故系統(tǒng)重啟之后,保存或者堆積在隊列中的消息丟失。
3.google的guava的個版本之間的兼容性也是一個問題,有時候會導(dǎo)致jar沖突導(dǎo)致服務(wù)無法啟動。如hive使用的是guava 11.0版本,而公司的內(nèi)部jar使用的是guava 22.0版本,程序啟動時出現(xiàn)了java.lang.NoSuchMethodError和ClassNoDef的異常。