激情五月播播久久久精品_国产激情偷乱视频一区二区三区_国产一区二区看久久_亚洲欧美成人网

當前位置: 首頁 >> 數碼 >
Guava的EventBus事件機制實現 全球視點
來源:程序猿阿嘴     時間:2023-04-25 06:40:19

EventBus說明

EventBus是Guava封裝的事件處理機制,屬于設計模式中的觀察者模式(生產|消費者編程模型)。使用簡單、優雅只關注業務本身,僅限JVM內部使用,缺點:不適用分布式,看實際業務可選用MQ。

事件總線(EventBus)處理個服務、或業務間公共線路,而EventBus則是存儲事件、處理時間中間服務,通過post()往EventBus發送事件,由EventBus去調度對應訂閱方(subscriber)消費處理,解耦觀察者模式中訂閱方與事件源之間強依賴關系。


(相關資料圖)

如何使用

引入Maven依賴
com.google.guavaguava20.0復制代碼
場景舉例(偽代碼)
public class EventBusCenter {    private static EventBus eventBus = new EventBus();    private EventBusCenter() {    }    public static EventBus getInstance(){        return eventBus;    }    /**注冊監聽*/    public static void register(Object listener){        eventBus.register(listener);    }    /**取消注冊*/    public static void unregister(Object listener){        eventBus.unregister(listener);    }    /**發布事件*/    public static void post(Object event){        eventBus.post(event);    }}復制代碼

定義業務對象

public class OrderInfo {    private long orderId;    private String orderName; }  public class OrderFailInfo{    private long orderId;    private String orderName;    private String msg;}復制代碼

支付成功監聽處理事件

public class OrderSuccessListener {    @Subscribe    public void orderSubscribe(OrderInfo event) {        // 訂單業務監聽        System.out.println("訂單支付成功處理事件: " + event);    }    @Subscribe    public void ortherSubscribe(OrderInfo event) {        // 其它業務監聽        System.out.println("訂單支付成功其它處理事件: " + event);    }}復制代碼

支付失敗監聽處理事件

public class OrderFailListener {    @Subscribe    public void orderSubscribe(OrderFailInfo event) {        // 訂單業務監聽        System.err.println("訂單支付失敗處理事件: " + event);    }    @Subscribe    public void ortherSubscribe(String event) {        // 其它業務監聽        System.err.println("訂單支付失敗其它處理事件: " + event);    }}復制代碼

測試

public class EventBusTest {    public static void main(String[] args) {        OrderSuccessListener successListener = new OrderSuccessListener();        OrderFailListener failListener = new OrderFailListener();            EventBusCenter.register(successListener);            EventBusCenter.register(failListener);            OrderInfo order = OrderInfo.builder().orderId(111L).orderName("訂單名稱xxx").build();            log.info("=====支付成功=======");            EventBusCenter.post(order);            log.info("=====支付失敗=======");            OrderFailInfo orderFail = OrderFailInfo.builder().orderId(111L).orderName("訂單名稱xxx").msg("支付失敗").build();            EventBusCenter.post(orderFail);            log.info("=====記錄支付失敗原因=======");            EventBusCenter.post("用戶取消訂單");    }}輸出結果:信息: =====支付成功=======訂單支付成功其它處理事件: OrderInfo(orderId=111, orderName=訂單名稱xxx)訂單支付成功處理事件: OrderInfo(orderId=111, orderName=訂單名稱xxx)信息: =====支付失敗=======訂單支付失敗處理事件: OrderFailInfo(orderId=111, orderName=訂單名稱xxx, msg=支付失敗)信息: =====記錄支付失敗原因=======訂單支付失敗其它處理事件: 用戶取消訂單復制代碼

使用說明:

只有通過***@Subscribe***注解才會被注冊進EventBus 監聽方法只能有1個參數,當有多個監聽方法時,參數類型一樣并行消費;不同參類型對應不對消費事件

源碼分析

初始化EvenBus

EventBus(String identifier, Executor executor, Dispatcher dispatcher, SubscriberExceptionHandler exceptionHandler) {        this.subscribers = new SubscriberRegistry(this);//所有觀察者列表維護對象        this.identifier = (String) Preconditions.checkNotNull(identifier);// EventBus的處理標識符(方法名稱)        //executor是事件分發過程中使用到的線程池,可以自己實現        this.executor = (Executor)Preconditions.checkNotNull(executor);        //Dispatcher類型的子類,對監聽者分發策略,主要有3種方式        this.dispatcher = (Dispatcher)Preconditions.checkNotNull(dispatcher);        //異常處理策咯        this.exceptionHandler = (SubscriberExceptionHandler)Preconditions.checkNotNull(exceptionHandler);    }復制代碼

注冊監聽–>register()

作用:初始化監聽者類型與監聽方法的集合 subscribers ,在 發布事件 場景由傳入參數類型,匹配、并執行對應監聽者方法

①獲取指定監聽者對應的全部觀察者集合(一對多)

②獲取對應**@Subscribe**觀察者事件類型(即:方法參數類型)集合

③添加對應類型所有觀察者到集合事件集合中(即:SubscriberRegistry對象維護的 subscribers 集合)

subscribers說明:

private final ConcurrentMap, CopyOnWriteArraySet>subscribers = Maps.newConcurrentMap();復制代碼

防止并發問題維護一個ConcurrentMap集合,Subscriber集合對應velue使用的是Java中的CopyOnWriteArraySet集合,

主要作用:1、避免監聽重復事件 2、適用于讀多寫少的場景:只要register()才寫入,基本都是查詢

findAllSubscribers()說明

①獲取注冊監聽對象所有包含**@Subscribe**的方法(如下圖所示??)

②通過反射獲取對應方法、及監聽參數類型

③放入當前初始化的EventBus對象里面,維護監聽對象與監聽方法的對應關系

首先從 subscriberMethodsCache 緩存中獲取監聽對象映射關系,如果緩存中不存在通過反射遍歷所有包含**@Subscribe**的方法

發布事件–>post()

①getSubscribers()方法獲取該事件對應的全部觀察者

②Dispatcher-分發事件策略

ImmediateDispatcher:直接在當前線程中遍歷所有的觀察者并進行事件分發

LegacyAsyncDispatcher:使用 全局隊列 ,先將觀察者依次放入隊列,再順序從隊列中取出觀察者對象進行事件分發

PerThreadQueuedDispatcher(默認):使用 線程相關隊列 ,會先獲取當前線程的觀察者隊列,并將傳入的觀察者列表傳入到該隊列中;判斷當前線程是否正在進行分發操作,如果沒有在進行分發操作,就通過遍歷上述隊列進行事件分發

最后無論使用哪個分發器,都會執行dispatchEvent()方法,通過反射(target、method、executor)多線程觸發監聽方法

原文鏈接:https://juejin.cn/post/7224310314807083065

標簽:
推薦新聞 +
猜您喜歡 +
主站蜘蛛池模板: 日本成人中文字幕在线| 激情视频综合网| 日本视频久久久| 欧美在线视频一二三| 日韩精品欧美专区| 国产欧美日韩91| 久久99精品久久久久久青青日本| 亚洲精品第一区二区三区| 国产欧美日韩最新| 久久精品国亚洲| 欧洲精品久久| 日本一区二区三区免费看 | 免费在线观看一区二区| 在线不卡日本| 91九色国产社区在线观看| 国产精品日韩二区| 久久99久久99精品免观看粉嫩| 欧美精品卡一卡二| 欧美综合在线第二页| 日本一区二区三区四区在线观看| 日韩中文字幕第一页| 日韩一区视频在线| 奇米888一区二区三区| 欧美日韩精品在线一区二区| 欧美综合第一页| 免费av在线一区| 久久久久久久免费视频| 国产精品视频内| 91精品国产一区| 亚洲日本无吗高清不卡| 午夜一区二区三区| 日韩一区二区在线视频| 欧美精品v日韩精品v国产精品| 欧美日韩一区在线观看视频| 欧美亚洲国产成人| 久久国产午夜精品理论片最新版本| 九九热精品在线| www.亚洲一区| 日韩一级黄色av| 久久久久久亚洲精品不卡| 国产欧美一区二区三区不卡高清|