詳解Guava中EventBus的使用
Guava EventBus
EventBus是Guava的事件處理機制,是設計模式中觀察者模式(生產/消費者編程模型)的優(yōu)雅實現(xiàn)。對于事件監(jiān)聽和發(fā)布訂閱模式,EventBus使用非常簡單便捷。

如果你做過CS的開發(fā),下面這段代碼可能會比較熟悉。
Button?button?=?new?Button("確定");
button.addListener(?new?Listener(){
????...
????public?void?onClick(Event?event){
????????//?
????}
????...
}?);
為按鈕注冊事件監(jiān)聽,當按鈕被點擊時,則觸發(fā)監(jiān)聽中相應的回調。在上面的代碼中,有三個角色事件(Event),事件源(Button),監(jiān)聽(Listener),按鈕作為事件源,當點擊行為觸發(fā)時,會將該行為封裝成對應的點擊事件,并根據(jù)行為類型將事件傳遞到響應的監(jiān)聽器上, 這也就是我們常說的監(jiān)聽器模式。
使用場景
實現(xiàn)消息生產者與消費者間的解耦,對應事件源與監(jiān)聽器,而消息則是事件
通過事件驅動業(yè)務流程扭轉,通過異步執(zhí)行機制實現(xiàn)代碼非阻塞執(zhí)行
擴展主線外的分支業(yè)務,減少代碼的侵入,比如各個環(huán)節(jié)的消息通知、短信提醒等
實現(xiàn)消息廣播到不同的模塊中
示例
訂單支付時的消息發(fā)送
//?商品
public?class?ProductOrder?{
????private?String?user;?//?用戶
????private?String?product;?//?商品
????private?double?amount;?//?金額
????@Override
????public?String?toString()?{
????????return?String.format("用戶:%s購買了商品:%s,總金額:%s",?user,?product,?amount);
????}
}
//?事件
????@Data
????@AllArgsConstructor
????public?static?class?CreateOrderEvent?implements?OrderEvent{
????????private?ProductOrder?order;
????}
//?監(jiān)聽
????public?static?class?CreateOrderListener{
????????@Subscribe
????????public?void?onEvent(CreateOrderEvent?event)?{
????????????log.info("創(chuàng)建訂單:{}",?event.getOrder());
????????}
????}
測試: 我們可以定義各種事件,比如訂單創(chuàng)建、訂單取消、訂單支付... 只需要簡單的三個步驟即可:
//?1.?創(chuàng)建事件總線 ????EventBus?eventBus?=?new?EventBus(?ProductOrder.class.getName()?); //?2.?注冊事件監(jiān)聽 ????eventBus.register(?new?CreateOrderListener()?); ????eventBus.register(?new?PayOrderListener()?); ????eventBus.register(?new?CancelOrderListener()?); ????eventBus.register(?new?RenewOrderListener()?); //?3.?發(fā)送事件通知 ????eventBus.post(new?ProductOrder.CreateOrderEvent(order)); ????TimeUnit.SECONDS.sleep(1); ????eventBus.post(new?ProductOrder.CancelOrderEvent(order)); ????TimeUnit.SECONDS.sleep(1); ????eventBus.post(new?ProductOrder.RenewOrderEvent(order)); ????TimeUnit.SECONDS.sleep(1); ????eventBus.post(new?ProductOrder.PayOrderEvent(order)); ????TimeUnit.SECONDS.sleep(5); ????eventBus.post(new?ProductOrder.ReturnOrderEvent(order));
同時我們可以通過AsyncEventBus建立事件異步總線,這樣在事件被觸發(fā)時,可以異步通知監(jiān)聽者完成事件回調,以此來提高響應速度。
核心
EventBus
事件總線,可以理解為事件與監(jiān)聽器的上下文,主要實現(xiàn)事件的注冊、事件的分發(fā)、以及監(jiān)聽器的回調,主要提供的方法包括:
- register 注冊監(jiān)聽,將監(jiān)聽器注冊到事件總線,通過注解@Subscribe通知其監(jiān)聽的事件類型(第一個方法參數(shù)類型)
- unregister 卸載監(jiān)聽,從事件總線移除監(jiān)聽
- post 發(fā)送事件通知,根據(jù)post事件類型,找到所有訂閱了該類型事件的監(jiān)聽器,并將事件推送到監(jiān)聽器對應的監(jiān)聽方法
Subscribe
通過@Subscribe標識監(jiān)聽器所關注的事件類型
Event
可以是任何對象,當然不建議將基礎類型或String作為事件類型,這樣就沒法做到按類型區(qū)分了

通過上面的圖就可以很清楚各個各個組件的職責,以及如何通過事件總線完成事件向監(jiān)聽的傳播,最終基于事件回調機制完成消息傳遞?;谑录寗拥姆漳P?/p>
上面這種結構的圖形是不是在很多位置都見過,這是一種經典的設計模式。試想一下,我們不通過事件驅動行為時,一般你們怎么寫代碼,通過ifelse?或者其他有著異曲同工的 實現(xiàn)方法,目的最后都是一樣?;贕uava提供的工具,我們不僅在使用時只需要簡單的三個步驟就能實現(xiàn),同樣,當需要屏蔽該功能時只需要去掉register一行即可,對整體功能 也沒有任何的影響。
在我們引入某種設計模式,某種架構模型時,總的目的都是為了降低代碼模塊間的耦合度,提升代碼整體的可讀性,最終讓代碼能夠易于維護性,或者有一定的復用性。
總結
事件監(jiān)聽模式、觀察者模式、發(fā)布訂閱模式,都是非常的相似,通過建立事件與監(jiān)聽器、觀察者與被觀察者、生產者與消費者者間消息傳遞媒介(示例中的事件總線EventBus),
不僅能夠使消息的發(fā)起者與接收者之間進行解耦,最主要的是通過消息傳遞渠道實現(xiàn)消息異步傳播,提升系統(tǒng)效率
到此這篇關于詳解Guava中EventBus的使用的文章就介紹到這了,更多相關Guava EventBus內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java使用Hutool執(zhí)行日期的加法和減法操作方法
使用Hutool進行日期的加法和減法操作,可以使用`DateUtil.offsetXXX()`方法來實現(xiàn),這些方法會返回一個新的日期,而不是在原日期上進行修改,本文給大家介紹Java使用Hutool執(zhí)行日期的加法和減法操作方法,感興趣的朋友一起看看吧2023-11-11
Springboot 整合通用mapper和pagehelper展示分頁數(shù)據(jù)的問題(附github源碼)
這篇文章主要介紹了Springboot 整合通用mapper和pagehelper展示分頁數(shù)據(jù)(附github源碼),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-09-09
WebSocket實現(xiàn)數(shù)據(jù)庫更新時前端頁面刷新
這篇文章主要為大家詳細介紹了WebSocket實現(xiàn)數(shù)據(jù)庫更新時前端頁面刷新,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-04-04
Spring?Boot中的過濾器攔截器監(jiān)聽器使用技巧匯總
本文將介紹在Spring?Boot應用程序中使用過濾器、攔截器和監(jiān)聽器的使用技巧,我們將討論它們之間的區(qū)別,以及何時使用它們,我們還將提供代碼示例,以幫助您在自己的應用程序中使用它們2023-12-12
基于Map的computeIfAbsent的使用場景和使用方式
這篇文章主要介紹了基于Map的computeIfAbsent的使用場景和使用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09
SpringBoot使用不同環(huán)境動態(tài)加載不同配置文件
通過在resource目錄下創(chuàng)建不同環(huán)境的配置文件,并在Spring?Boot啟動類中使用環(huán)境變量來加載相應的配置文件,從而實現(xiàn)不同環(huán)境下的配置自動加載2024-11-11

