首頁  >  文章  >  Java  >  Java-類別庫-Guava-EventBus

Java-類別庫-Guava-EventBus

黄舟
黄舟原創
2017-01-19 13:12:551495瀏覽

  EventBus是Guava的事件處理機制,是設計模式中的觀察者模式(生產/消費者程式設計模型)的優雅實現。對於事件監聽和發布訂閱模式,EventBus是一個非常優雅和簡單解決方案,我們不用創建複雜的類別和介面層次結構。

  Observer模式是比較常用的設計模式之一,雖然有時候在具體程式碼裡,它不一定叫這個名字,例如改頭換面叫個Listener,但模式就是這個模式。手工實作一個Observer也不是多複雜的一件事,只是因為這個設計模式實在太常用了,Java就把它放到了JDK裡面:Observable和Observer,從JDK 1.0裡,它們就一直在那裡。從某種程度上說,它簡化了Observer模式的開發,至少我們不用再手動維護自己的Observer清單了。不過,如前所述,JDK裡的Observer從1.0就在那裡了,直到Java 7,它都沒有什麼改變,就連通知的參數還是Object類型。要知道,Java 5就已經泛型了。 Java 5是大規模的語法調整,許多程式庫從那開始重新設計了API,使其更簡潔易用。當然,那些不做應對的程式庫,多半也就過時了。這也就是這裡要討論知識更新的原因。今天,對於普通的應用,如果要使用Observer模式該如何做呢?答案是Guava的EventBus。 

  EventBus基本用法:

  使用Guava之後, 如果要訂閱訊息, 就不用再繼承指定的介面, 只需要在指定的方法上加上@Subscribe註解即可。程式碼如下:

  訊息封裝類別: 

[code]public class TestEvent {
    private final int message;
    public TestEvent(int message) {        
        this.message = message;
        System.out.println("event message:"+message);
    }
    public int getMessage() {
        return message;
    }
}

 訊息接受類別: 

[code]public class EventListener {
    public int lastMessage = 0;

    @Subscribe
    public void listen(TestEvent event) {
        lastMessage = event.getMessage();
        System.out.println("Message:"+lastMessage);
    }

    public int getLastMessage() {      
        return lastMessage;
    }
}

測試類別及輸出結果:

[code]public class TestEventBus {
    @Test
    public void testReceiveEvent() throws Exception {

        EventBus eventBus = new EventBus("test");
        EventListener listener = new EventListener();

        eventBus.register(listener);

        eventBus.post(new TestEvent(200));
        eventBus.post(new TestEvent(300));
        eventBus.post(new TestEvent(400));

        System.out.println("LastMessage:"+listener.getLastMessage());
        ;
    }
}

//输出信息
event message:200
Message:200
event message:300
Message:300
event message:400
Message:400
LastMessage:400

 MulList可實現多個訊息的訂閱,代碼如下: 

[code]public class MultipleListener {
    public Integer lastInteger;  
    public Long lastLong;  

    @Subscribe  
    public void listenInteger(Integer event) {  
        lastInteger = event; 
        System.out.println("event Integer:"+lastInteger);
    }  

    @Subscribe  
    public void listenLong(Long event) {  
        lastLong = event; 
        System.out.println("event Long:"+lastLong);
    }  

    public Integer getLastInteger() {  
        return lastInteger;  
    }  

    public Long getLastLong() {  
        return lastLong;  
    }  
}
[code]public class TestMultipleEvents {
    @Test  
    public void testMultipleEvents() throws Exception {  

        EventBus eventBus = new EventBus("test");  
        MultipleListener multiListener = new MultipleListener();  

        eventBus.register(multiListener);  

        eventBus.post(new Integer(100));
        eventBus.post(new Integer(200));  
        eventBus.post(new Integer(300));  
        eventBus.post(new Long(800)); 
        eventBus.post(new Long(800990));  
        eventBus.post(new Long(800882934));  

        System.out.println("LastInteger:"+multiListener.getLastInteger());
        System.out.println("LastLong:"+multiListener.getLastLong());
    }   
}

//输出信息
event Integer:100
event Integer:200
event Integer:300
event Long:800
event Long:800990
event Long:800882934
LastInteger:300
LastLong:800882934

Dead Event:

  如果EventBus發送的訊息都不是訂閱者關心的稱之為Dead Event。實例如下 

[code]public class DeadEventListener {
    boolean notDelivered = false;  

    @Subscribe  
    public void listen(DeadEvent event) {  

        notDelivered = true;  
    }  

    public boolean isNotDelivered() {  
        return notDelivered;  
    }  
}
[code]public class DeadEventListener {
    boolean notDelivered = false;  

    @Subscribe  
    public void listen(DeadEvent event) {  

        notDelivered = true;  
    }  

    public boolean isNotDelivered() {  
        return notDelivered;  
    }  
}

說明:如果沒有訊息訂閱者監聽訊息, EventBus將發送DeadEvent訊息,這時我們可以透過log的方式來記錄這個狀態。

  Event的繼承:


  如果Listener A監聽Event A, 而Event A有一個子類別Event B, 此時Listener A將同時接收Event A和B訊息,實例如下:

 〜〕 :在這個方法中,我們看到第一個事件(新的整數(100))是收到兩個聽眾,但第二個(新長(200 l))只能到達NumberListener作為整數一不是創建這種類型的事件。可以使用此功能來建立更通用的監聽器監聽一個廣泛的事件和更詳細的具體的特殊的事件。

  一個綜合實例:

[code]public class NumberListener {  

    private Number lastMessage;  

    @Subscribe  
    public void listen(Number integer) {  
        lastMessage = integer; 
        System.out.println("Message:"+lastMessage);
    }  

    public Number getLastMessage() {  
        return lastMessage;  
    }  
}  

public class IntegerListener {  

    private Integer lastMessage;  

    @Subscribe  
    public void listen(Integer integer) {  
        lastMessage = integer; 
        System.out.println("Message:"+lastMessage);
    }  

    public Integer getLastMessage() {  
        return lastMessage;  
    }  
}
[code]public class TestEventsFromSubclass {
    @Test  
    public void testEventsFromSubclass() throws Exception {  

        EventBus eventBus = new EventBus("test");  
        IntegerListener integerListener = new IntegerListener();  
        NumberListener numberListener = new NumberListener();  
        eventBus.register(integerListener);  
        eventBus.register(numberListener);  

        eventBus.post(new Integer(100));  

        System.out.println("integerListener message:"+integerListener.getLastMessage());
        System.out.println("numberListener message:"+numberListener.getLastMessage());

        eventBus.post(new Long(200L));  

        System.out.println("integerListener message:"+integerListener.getLastMessage());
        System.out.println("numberListener message:"+numberListener.getLastMessage());        
    }  
}

//输出类
Message:100
Message:100
integerListener message:100
numberListener message:100
Message:200
integerListener message:100
numberListener message:200

說明:用telnet指令登入:telnet 127.0.0.1 4444 ,如果你連接多個實例你會看到任何訊息傳送到其他實例


以上就是ava-Java -EventBus的內容,更多相關內容請關注PHP中文網(www.php.cn)!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn