ホームページ  >  記事  >  Java  >  Java クラス ライブラリ-Guava-EventBus

Java クラス ライブラリ-Guava-EventBus

黄舟
黄舟オリジナル
2017-01-19 13:12:551496ブラウズ

EventBus は、Guava のイベント処理メカニズムであり、デザイン パターンにおけるオブザーバー パターン (プロデューサー/コンシューマー プログラミング モデル) のエレガントな実装です。 EventBus は、イベント リスニングとパブリッシュ/サブスクライブ パターンのための非常に洗練されたシンプルなソリューションです。複雑なクラスやインターフェイスの階層を作成する必要はありません。

Observerパターンは、より一般的に使用されるデザインパターンの1つですが、特定のコードでは必ずしもこの名前で呼ばれない場合があります。たとえば、Listenerという名前に変更されますが、パターンはこのパターンです。オブザーバを手動で実装することは複雑なことではありません。この設計パターンは非常に一般的に使用されているため、Java はそれを JDK に組み込みました。Observable と Observer は JDK 1.0 から存在しています。これにより、オブザーバー パターンの開発がある程度簡素化され、少なくとも独自のオブザーバー リストを手動で管理する必要がなくなりました。ただし、前述したように、JDK の Observer は 1.0 から存在しており、通知のパラメーターも依然として 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


MultiListenerの使用方法:

サブスクライブするメソッドに @Subscribe アノテーションを追加するだけです。複数のメッセージのサブスクリプションを実現できます。コードは次のとおりです:

[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 メッセージを送信します。この時点で、このステータスをログに記録できます。

イベントの継承:

リスナー A がイベント A をリッスンし、イベント A にサブクラス イベント B がある場合、リスナー A はイベント A とイベント B のメッセージを同時に受信します。 例は次のとおりです。

リスナー クラス:

[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

説明: このメソッドでは、最初のイベント (new Integer(100)) は両方のリスナーによって受信されますが、2 番目のイベント (new Long(200l)) は、Integer イベントが作成されていないため、NumberListener にしか到達できないことがわかります。イベントの種類。この機能を使用すると、幅広いイベントをリッスンするより一般的なリスナーと、特定の特別なイベントをリッスンするより詳細なリスナーを作成できます。

包括的な例:

[code]public class UserThread extends Thread {
    private Socket connection;
    private EventBus channel;
    private BufferedReader in;
    private PrintWriter out;

    public UserThread(Socket connection, EventBus channel) {
        this.connection = connection;
        this.channel = channel;
        try {
            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            out = new PrintWriter(connection.getOutputStream(), true);
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    @Subscribe
    public void recieveMessage(String message) {
        if (out != null) {
            out.println(message);
            System.out.println("recieveMessage:"+message);
        }
    }

    @Override
    public void run() {
        try {
            String input;
            while ((input = in.readLine()) != null) {
                channel.post(input);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        //reached eof
        channel.unregister(this);
        try {
            connection.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        in = null;
        out = null;
    }
}
[code]mport java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

import com.google.common.eventbus.EventBus;

public class EventBusChat {
    public static void main(String[] args) {
        EventBus channel = new EventBus();
        ServerSocket socket;
        try {
            socket = new ServerSocket(4444);
            while (true) {
                Socket connection = socket.accept();
                UserThread newUser = new UserThread(connection, channel);
                channel.register(newUser);
                newUser.start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

説明: telnet コマンドを使用してログイン: telnet 127.0.0.1 4444. 複数のインスタンスに接続すると、送信されたメッセージが他のインスタンスに送信されることがわかります

上記は Java クラスですLibrary-Guava -EventBus コンテンツ。その他の関連コンテンツについては、PHP 中国語 Web サイト (www.php.cn) に注目してください。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。