摘要:文章鏈接之事件驅動機制的簡單使用之事件驅動機制的簡單使用關于事件的發起與相應,在客戶端的交互中可算是非常頻繁的事情了,關于事件的發布訂閱,在生態中,可謂是非常有名了,而也提供了事件機制,本文則主要介紹后端如何在的環境中,使用事件機制使用姿
文章鏈接:https://liuyueyi.github.io/hexblog/hexblog/2018/06/09/180609-Spring之事件驅動機制的簡單使用/
Spring之事件驅動機制的簡單使用關于事件的發起與相應,在客戶端的交互中可算是非常頻繁的事情了,關于事件的發布訂閱,在Java生態中,EventBus可謂是非常有名了,而Spring也提供了事件機制,本文則主要介紹后端如何在Spring的環境中,使用事件機制
I. 使用姿勢主要借助org.springframework.context.ApplicationEventPublisher#publishEvent(org.springframework.context.ApplicationEvent) 來發布事件,而接受方,則直接在處理的方法上,添加 @@EventListener注解即可
1. 事件定義發布一個事件,所以第一件事就是要定義一個事件,對Spring而言,要求自定義的事件繼承自ApplicationEvent類, 一個簡單的demo如下
public class NotifyEvent extends ApplicationEvent { @Getter private String msg; public NotifyEvent(Object source, String msg) { super(source); this.msg = msg; } }2. 發布事件
發布時間則比較簡單,直接拿到ApplicationContext實例,執行publish方法即可,如下面給出一個簡單的發布類
@Component public class NotifyPublisher implements ApplicationContextAware { private ApplicationContext apc; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.apc = applicationContext; } // 發布一個消息 public void publishEvent(int status, String msg) { if (status == 0) { apc.publishEvent(new NotifyEvent(this, msg)); } else { apc.publishEvent(new NewNotifyEvent(this, msg, ((int) System.currentTimeMillis() / 1000))); } } }3. 事件監聽器
在方法上添加注解即可,如下
@Component public class NotifyQueueListener { @EventListener public void consumerA(NotifyEvent notifyEvent) { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("A: " + Thread.currentThread().getName() + " | " + notifyEvent.getMsg()); } @EventListener public void consumerB(NewNotifyEvent notifyEvent) { System.out.println("B: " + Thread.currentThread().getName() + " | " + notifyEvent.getMsg()); } @EventListener public void consumerC(NotifyEvent notifyEvent) { System.out.println("C: " + Thread.currentThread().getName() + " | " + notifyEvent.getMsg()); } }II. 疑問及解答 1. 發布與監聽器的關聯
上面給出了使用的姿勢,看起來并不復雜,也比較容易使用,但是一個問題需要在使用之前弄明白了,發布事件和監聽器是怎么關聯起來的呢?
根據方法的參數類型執行
那么如果發布者,推送的是一個NotifyEvent類型的事件,那么接收者是怎樣的呢?
參數為NotifyEvent以及其子類的監聽器,都可以接收到消息
測試用例如下:
NewNotifyEvent 繼承自上面的NotifyEvent
public class NewNotifyEvent extends NotifyEvent { @Getter private int version; public NewNotifyEvent(Object source, String msg) { super(source, msg); } public NewNotifyEvent(Object source, String msg, int version) { super(source, msg); this.version = version; } }
然后借助上面的消息發布者發送一個消息
@Test public void testPublishEvent() throws InterruptedException { notifyPublisher.publishEvent(1, "新的發布事件! NewNotify"); System.out.println("---------"); notifyPublisher.publishEvent(0, "舊的發布事件! Notify"); }
輸出結果如下,對于NewNotifyEvent, 參數類型為NotifyEvent的consumerA, consumerC都可以接收到
A: main | 新的發布事件! NewNotify C: main | 新的發布事件! NewNotify B: main | 新的發布事件! NewNotify --------- A: main | 舊的發布事件! Notify C: main | 舊的發布事件! Notify2. 消息接收的順序
上面消息處理是串行的,那么先后順序怎么確定? (下面的答案不確定,有待深入源碼驗證?。。。?/p>
先掃描到的bean先處理
同一個bean中,按精確匹配,先后定義順序進行
3. 異步消費對于異步消費,即在消費者方法上添加一個@Async注解,并需要在配置文件中,開啟異步支持
@Async @EventListener public void processNewNotifyEvent(NewNotifyEvent newNotifyEvent) { System.out.println("new notifyevent: " + newNotifyEvent.getMsg() + " : " + newNotifyEvent.getVersion()); }
配置支持
@Configuration @EnableAsync public class AysncListenerConfig implements AsyncConfigurer { /** * 獲取異步線程池執行對象 * * @return */ @Override public Executor getAsyncExecutor() { return new ThreadPoolExecutor(5, 10, 1, TimeUnit.MINUTES, new LinkedBlockingQueueIII. 其他 一灰灰Blog: https://liuyueyi.github.io/he...(), new DefaultThreadFactory("test"), new ThreadPoolExecutor.CallerRunsPolicy()); } }
一灰灰的個人博客,記錄所有學習和工作中的博文,歡迎大家前去逛逛
聲明盡信書則不如,已上內容,純屬一家之言,因個人能力有限,難免有疏漏和錯誤之處,如發現bug或者有更好的建議,歡迎批評指正,不吝感激
微博地址: 小灰灰Blog
QQ: 一灰灰/3302797840
掃描關注文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69711.html
摘要:如果當前沒有事件也沒有定時器事件,則返回。相關資料關于的架構及設計思路的事件討論了使用線程池異步運行代碼。下一篇初窺事件機制的實現二中定時器的實現 在瀏覽器中,事件作為一個極為重要的機制,給予JavaScript響應用戶操作與DOM變化的能力;在Node.js中,事件驅動模型則是其高并發能力的基礎。 學習JavaScript也需要了解它的運行平臺,為了更好的理解JavaScript的事...
摘要:使用了一個事件驅動非阻塞式的模型,使其輕量又高效。的包管理器,是全球最大的開源庫生態系統。按照這個定義,之前所述的阻塞,非阻塞,多路復用信號驅動都屬于同步。 系列文章 Nodejs高性能原理(上) --- 異步非阻塞事件驅動模型Nodejs高性能原理(下) --- 事件循環詳解 前言 終于開始我nodejs的博客生涯了,先從基本的原理講起.以前寫過一篇瀏覽器執行機制的文章,和nodej...
摘要:一微服務概念微服務體系結構由輕量級松散耦合的服務集合組成。每個服務都有自己的計劃測試發布部署擴展集成和獨立維護。團隊不必因為過去的技術決定而受到懲罰。用在這里是指將相關的服務通過聚合器聚合在一起,這個聚合器就是門面。 微服務架構現在是談到企業應用架構時必聊的話題,微服務之所以火熱也是因為相對之前的應用開發方式有很多優點,如更靈活、更能適應現在需求快速變更的大環境。 一、微服務概念 微服...
摘要:由于是需要兼容的后臺系統,該項目并不能使用到等技術,因此我在上的經驗大都是使用原生的編寫的,可以看見一個組件分為兩部分視圖部分,和數據部分。 在公司里幫項目組里開發后臺系統的前端項目也有一段時間了。 vue這種數據驅動,組件化的框架和react很像,從一開始的快速上手基本的開發,到后來開始自定義組件,對element UI的組件二次封裝以滿足項目需求,期間也是踩了不少坑。由于將來很長一...
閱讀 2025·2023-04-25 14:50
閱讀 2907·2021-11-17 09:33
閱讀 2611·2019-08-30 13:07
閱讀 2838·2019-08-29 16:57
閱讀 908·2019-08-29 15:26
閱讀 3540·2019-08-29 13:08
閱讀 1990·2019-08-29 12:32
閱讀 3383·2019-08-26 13:57