Guava - EventBus(事件總線)


Guava在guava-libraries中為我們提供了事件總線EventBus庫,它是事件發布訂閱模式的實現,讓我們能在領域驅動設計(DDD)中以事件的弱引用本質對我們的模塊和領域邊界很好的解耦設計。

不再多的廢話,直奔Guava EventBus主題。首先Guava為我們提供了同步事件EventBus和異步實現AsyncEventBus兩個事件總線,他們都不是單例的,官方理由是並不想我們我們的使用方式。當然如果我們想其為單例,我們可以很容易封裝它,一個單例模式保證只創建一個實例就對了。

下面將以EventBus為例,AsyncEventBus使用方式與其一致的。

訂閱

首先EventBus為我們提供了register方法來訂閱事件,Guava在這里的實現很友好,我們不需要實現任何的額外接口或者base類,只需要在訂閱方法上標注上@Subscribe和保證只有一個輸入參數的方法就可以搞定。這樣對於簡單的某些事件,我們甚至可以直接

new Object() {

    @Subscribe
    public void lister(Integer integer) {
        System.out.printf("%d from int%n", integer);
    }
}

Guava發布的事件默認不會處理線程安全的,但我們可以標注@AllowConcurrentEvents來保證其線程安全

發布

對於事件源,則可以通過post方法發布事件。 正在這里對於Guava對於事件的發布,是依據上例中訂閱方法的方法參數類型決定的,換而言之就是post傳入的類型和其基類類型可以收到此事件。例如下例:

final EventBus eventBus = new EventBus();
eventBus.register(new Object() {

    @Subscribe
    public void lister(Integer integer) {
        System.out.printf("%s from int%n", integer);
    }

    @Subscribe
    public void lister(Number integer) {
        System.out.printf("%s from Number%n", integer);
    }

    @Subscribe
    public void lister(Long integer) {
        System.out.printf("%s from long%n", integer);
    }
});

eventBus.post(1);
eventBus.post(1L);

在這里有 Integer,Long,與它們基類Number。我們發送一個整數數據的時候,或者Integer和Number的方法接收,而Long類型則Long類型和Number類型接受。

所以博主建議對於每類事件封裝一個特定的事件類型是必要的。

DeadEvent

DeadEvent暫時不清楚怎么翻譯更合意,它描述的是死亡事件,即沒有沒任何訂閱者關心,沒有被處理,以DeadEvent類型參數的方法表示.例如在上例中我們post一個Object類型,如下:

final EventBus eventBus = new EventBus();
eventBus.register(new Object() {

    @Subscribe
    public void lister(DeadEvent event) {
        System.out.printf("%s=%s from dead events%n", event.getSource().getClass(), event.getEvent());
    }
});

eventBus.post(new Object());

更多Guava博文:

  1. Guava – 並行編程Futures
  2. Guava – EventBus(事件總線)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM