ホームページ Java &#&チュートリアル Java クラス ライブラリ-Guava-EventBus

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

Jan 19, 2017 pm 01:12 PM

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 までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Javaの平方根 Javaの平方根 Aug 30, 2024 pm 04:26 PM

Java の平方根のガイド。ここでは、Java で平方根がどのように機能するかを、例とそのコード実装をそれぞれ示して説明します。

Javaの完全数 Javaの完全数 Aug 30, 2024 pm 04:28 PM

Java における完全数のガイド。ここでは、定義、Java で完全数を確認する方法、コード実装の例について説明します。

Java の乱数ジェネレーター Java の乱数ジェネレーター Aug 30, 2024 pm 04:27 PM

Java の乱数ジェネレーターのガイド。ここでは、Java の関数について例を挙げて説明し、2 つの異なるジェネレーターについて例を挙げて説明します。

ジャワのウェカ ジャワのウェカ Aug 30, 2024 pm 04:28 PM

Java の Weka へのガイド。ここでは、weka java の概要、使い方、プラットフォームの種類、利点について例を交えて説明します。

Javaのアームストロング数 Javaのアームストロング数 Aug 30, 2024 pm 04:26 PM

Java のアームストロング番号に関するガイド。ここでは、Java でのアームストロング数の概要とコードの一部について説明します。

Javaのスミス番号 Javaのスミス番号 Aug 30, 2024 pm 04:28 PM

Java のスミス番号のガイド。ここでは定義、Java でスミス番号を確認する方法について説明します。コード実装の例。

Java Springのインタビューの質問 Java Springのインタビューの質問 Aug 30, 2024 pm 04:29 PM

この記事では、Java Spring の面接で最もよく聞かれる質問とその詳細な回答をまとめました。面接を突破できるように。

Java 8 Stream Foreachから休憩または戻ってきますか? Java 8 Stream Foreachから休憩または戻ってきますか? Feb 07, 2025 pm 12:09 PM

Java 8は、Stream APIを導入し、データ収集を処理する強力で表現力のある方法を提供します。ただし、ストリームを使用する際の一般的な質問は次のとおりです。 従来のループにより、早期の中断やリターンが可能になりますが、StreamのForeachメソッドはこの方法を直接サポートしていません。この記事では、理由を説明し、ストリーム処理システムに早期終了を実装するための代替方法を調査します。 さらに読み取り:JavaストリームAPIの改善 ストリームを理解してください Foreachメソッドは、ストリーム内の各要素で1つの操作を実行する端末操作です。その設計意図はです

See all articles