ホームページ >Java >&#&チュートリアル >Java クラス ライブラリ-Guava-EventBus
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) に注目してください。