日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java spring eventbus_spring集成guava的event bus

發(fā)布時間:2023/12/3 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java spring eventbus_spring集成guava的event bus 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Guava的event bus

guava,?https://github.com/google/guava 是一個非常有名的Java類庫,提供了很多在日常開發(fā)中常用的集合、函數(shù)接口等。此外,guava還提供了一個模塊叫做event bus,生產(chǎn)者往event bus上投遞消息,event bus負責回調(diào)訂閱了此類消息的回調(diào)函數(shù),實現(xiàn)了消息生產(chǎn)者和消費者之間的解耦和異步處理。以下是一個簡單的例子:

public classSimpleListener {

@Subscribepublic voidtask(String s) {

System.out.println("do task(" + s + ")");

}

}

public classSimpleEventBusExample {public static voidmain(String[] args) {

EventBus eventBus= newEventBus();

eventBus.register(newSimpleListener());

System.out.println("Post Simple EventBus Example");

eventBus.post("Simple EventBus Example");

}

}

output

Post Simple EventBus Exampledo task(Simple EventBus Example)

event bus集成到spring中

在之前的例子和guava的官方文檔里面可以看到,guava的event bus使用方式如下

1. 聲明一個event bus對象(線程安全,所以可以做到全局唯一,而且訂閱者和發(fā)布者必須共享這個event bus對象)

2. 對于訂閱者,支持?@Subscribe,定義處理消息的回調(diào)函數(shù)。

3. 對每一個訂閱者,需要調(diào)用event bus的register方法,才能收到消息訂閱。

對于1 和 2,都比較好。但是對于第3步來說,則有一點困難。因為

1. 在spring中,通常的你的訂閱者還會依賴其他的spring管理的bean,于是你的訂閱者也會被納入到spring的生命周期的管理中來,這樣如果用new的方式來初始化一個訂閱者,顯得非常的"不spring"。

2. 對于每個訂閱者,都要顯式的注冊到event bus里面,這樣并沒有做到關注點分離。理想的情況下,訂閱者是不應該去關注如何注冊到event bus中。它只應該申明處理消息的回調(diào)函數(shù),以及該回調(diào)函數(shù)是否能夠并發(fā)調(diào)用。注冊到event bus中這件事,對于訂閱者應該是被動且自動的(只需要申明自己是否想注冊到event bus,而不需要關心細節(jié))。這一點在多人開發(fā),并且項目人員水平參差不齊的時候,尤其重要。

那么如何做到自動注冊呢?其實答案很簡單,在spring中,ApplicationContext這個類提供了一系列的方法去獲取到當前spring context中的bean,只需要在event bus初始化之后,通過ApplicationContext來獲取當前有哪些訂閱者,并且主動的去注冊就行。由于,guava的實現(xiàn)中,并沒有要求訂閱者實現(xiàn)某個接口,而是用注解的方式來聲明回調(diào)函數(shù)的,則這篇文章中的實現(xiàn),也不需要訂閱者去實現(xiàn)某個接口,而是用注解的方式來申明自己是一個訂閱者。代碼如下

先聲明一個注解

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Servicepublic @interfaceEventSubscriber {}

對于一個訂閱者,在類的接口上,加上這個注解,并且確定這個bean會在納入spring的生命周期管理中。

@EventSubscriberpublic class SimpleSubscriber implementsHiDasSubscriber {

@Autowired

Somebean somebean;

@Subscribe

@AllowConcurrentEventspublicInteger logEventToDbAndUpdateStatus(String event) {

System.out.println("receive a event:"+event);

}

}

聲明一個event bus的服務,并且在初始化之后,通過ApplicationContext的?getBeansWithAnnotation 的方法把所有的訂閱者獲取,并且注冊到event bus中。

@Servicepublic class EventBusService implementsInitializingBean{privateEventBus innerBus;

@InjectprivateApplicationContext appContext;public voidunRegister(Object eventListener){

innerBus.unregister(eventListener);

}public voidpostEvent(String event){

innerBus.post(event);

}public voidregister(Object eventListener){

innerBus.register(eventListener);

}

@Overridepublic void afterPropertiesSet() throwsException {

innerBus= new AsyncEventBus("Hidas-event-bus", Executors.newCachedThreadPool());

appContext.getBeansWithAnnotation(EventSubscriber.class).forEach((name, bean) ->{

innerBus.register(bean);

});

}

}

完成了這兩步之后。如果其他的消息生產(chǎn)者要往event bus上發(fā)消息,只需要注入這個event bus service,并且調(diào)用其post方法就好了。

注:這個只是例子,在實際項目中,對所有的消息都會聲明一個基類或者接口,每個訂閱者對只會處理消息的某個具體實現(xiàn)。這樣event bus會根據(jù)消息的具體類型,來調(diào)用真正關注此類消息的訂閱者的回調(diào)函數(shù)。這樣比起讓所有消息訂閱者去實現(xiàn)一個 onEvent(BaseEvent event)的方法,?實際上是避免了一個多路分配的問題。

總結(jié)

對于一些類庫在spring中使用,這種方法實際上是一種通用的模式,實現(xiàn)某個接口或者編寫某個注解,然后通過ApplicationContext來獲取對應的bean,之后進行某些注冊或者組裝操作。這樣的話,可以讓業(yè)務的代碼,和框架的代碼做到一定程度的關注點分離。

總結(jié)

以上是生活随笔為你收集整理的java spring eventbus_spring集成guava的event bus的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。