番石榴的EventBus –简单的发布者/订阅者
在查看Google的Guava Libraries 版本10的最新版本時,我注意到EventBus的添加。 這是發(fā)布-訂閱樣式消息傳遞系統(tǒng)的輕量級實(shí)現(xiàn)。 這類似于JMS提供的發(fā)布-訂閱模型,但是消息保留在應(yīng)用程序內(nèi),而不是在外部廣播。
EventBus允許您在程序中創(chuàng)建對象可以訂閱的流; 然后,他們將接收發(fā)布到這些流的消息。 盡管使用諸如單例之類的模式來重新創(chuàng)建對象間通信并不是特別困難,但EventBus確實(shí)提供了一種特別簡單且輕巧的機(jī)制。 單例還使具有單一類型的多個事件總線更加困難,并且
很難測試。
例如,我將使用幾個人將通過telnet連接到的套接字創(chuàng)建一個簡單的多用戶聊天程序。 我們將簡單地創(chuàng)建一個EventBus作為通道。 用戶發(fā)送給系統(tǒng)的任何消息都將發(fā)布給所有其他用戶。
所以這是我們的UserThread對象:
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);}}@Subscribepublic void recieveMessage(String message) {if (out != null) {out.println(message);}}@Overridepublic void run() {try {String input;while ((input = in.readLine()) != null) {channel.post(input);}} catch (IOException e) {e.printStackTrace();}//reached eofchannel.unregister(this)try {connection.close();} catch (IOException e) {e.printStackTrace();}in = null;out = null;} }可以看出,這只是一個簡單的線程對象,其中包含充當(dāng)通道的EventBus和用戶的Socket。 然后,run方法通過調(diào)用EventBus上的post方法簡單地讀取套接字并將消息發(fā)送到通道。
然后,通過添加帶有@Subscribe批注的公共方法來實(shí)現(xiàn)接收消息(請參見上文)。 這表示EventBus在收到方法參數(shù)中給定類型的消息后調(diào)用此方法。 我在這里發(fā)送字符串,但是可以使用其他對象。
GOTCHA :用@Subscribe注釋的方法必須是公共的。
接收功能接收消息并將其寫出到用戶的連接中。 當(dāng)然,這還將回送已發(fā)送給原始用戶的消息,因為UserThread對象本身將接收其發(fā)布的消息。
剩下的就是創(chuàng)建一個簡單的服務(wù)器對象,該對象偵聽連接并根據(jù)需要創(chuàng)建UserThread對象。
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();}} }如圖所示,這將創(chuàng)建通道,接受用戶連接并將其注冊到EventBus。 這里要注意的重要代碼是使用UserThread對象作為參數(shù)調(diào)用register方法。 該調(diào)用在EventBus上預(yù)訂對象,并指示它可以處理消息。
服務(wù)器啟動后,用戶即可使用telnet命令連接到聊天服務(wù)器:
telnet 127.0.0.1 4444而且,如果您連接多個實(shí)例,您將看到發(fā)送的任何消息都被中繼到其他實(shí)例。
看完此示例后,您可能想知道EventBus有什么用。 一個很好的例子是在用戶界面和后端代碼之間保持非常松散的耦合。 用戶輸入將生成一條消息,例如調(diào)整大小,失去焦點(diǎn)或關(guān)閉。 然后,后端組件可以簡單地訂閱這些事件并適當(dāng)?shù)靥幚硭鼈儭?官方文檔還列出了許多其他用途。
注意: EventBus并非用于通用的發(fā)布者-訂閱者通信,這只是API交互方式的一個示例。
原文: http : //insightfullogic.com/blog/2011/oct/10/eventbus/
翻譯自: https://www.javacodegeeks.com/2013/06/guavas-eventbus-simple-publishersubscriber.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的番石榴的EventBus –简单的发布者/订阅者的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring Data Solr教程:动
- 下一篇: 使用Apache CXF开发RESTfu