Spring事件監(jiān)聽基本原理與使用詳解
一、簡介
1、Spring事件監(jiān)聽基本原理
Spring的事件監(jiān)聽機制和發(fā)布訂閱機制是很相似的:發(fā)布了一個事件后,監(jiān)聽該類型事件的所有監(jiān)聽器會觸發(fā)相應(yīng)的處理邏輯。
正如Spring官方文檔上所說的,整個上就是一個觀察者的模式。那么,我們不妨猜測下,Spring是如何來實現(xiàn)事件發(fā)布監(jiān)聽的:底層使用一個集合存儲了所有的監(jiān)聽器,當(dāng)發(fā)布了一個事件后,遍歷事件監(jiān)聽器集合,然后過濾符合事件類型的監(jiān)聽器,最后觸發(fā)相應(yīng)的事件處理邏輯。
2、Spring中事件監(jiān)聽的相關(guān)規(guī)范
在Spring中,事件監(jiān)聽機制主要涉及到了一下幾個關(guān)鍵的規(guī)范(抽象類及接口):ApplicationEvent、ApplicationListener、ApplicationEventPublisher
- ApplicationEvent: Spring的事件是符合jdk的規(guī)范的,這個抽象類繼承了jdk內(nèi)置的事件規(guī)范類EventObject(即jdk建議所有的事件都繼承EventObject這個類)。ApplicationEvent是Spring家的事件規(guī)范。所以我們在自定義事件的時候,可以繼承與ApplicationEvent,比如,Spring家自己關(guān)于容器上下文事件就又定義了一個容器上下文的時間規(guī)范ApplicationContextEvent,它同樣是繼承于ApplicationEvent的,只不過擴充了獲取發(fā)出事件容器的方法;今后,我們同樣可以在繼承于ApplicationEvent的基礎(chǔ)上定義自己的事件規(guī)范。
- ApplicationListener:這是一個函數(shù)式接口,同樣時事件監(jiān)聽器的規(guī)范,當(dāng)監(jiān)聽到自己監(jiān)聽的事件類型時就會調(diào)用onApplicationEvent方法來執(zhí)行監(jiān)聽邏輯
- ApplicationEventPublisher:這同樣是一個函數(shù)式接口,定義了事件發(fā)布的規(guī)范,任何的事件發(fā)布器ApplicationEventPublisher都是通過調(diào)用publishEvent來進行事件的發(fā)布
二、Spring事件監(jiān)聽器的使用
1、自定義事件創(chuàng)建
在Spring中,所有的事件需要繼承自ApplicationEvent,自定義事件的不同可以監(jiān)聽多個,一個最基礎(chǔ)的MsgEvent如下
public class MyEvent extends ApplicationEvent { private String msg; // 必須繼承實現(xiàn) public MyEvent(Object source, String msg) { super(source); this.msg = msg; } @Override public String toString() { return "MyEvent{" + "msg='" + msg + '\'' + '}'; } }
2、自定義監(jiān)聽器
2.1 方法介紹
springboot進行事件監(jiān)聽有四種方式,選擇任意一種即可
- 將監(jiān)聽器裝載入spring容器(常用)
- 通過@EventListener注解實現(xiàn)事件監(jiān)聽(常用)
- 手工向ApplicationContext中添加監(jiān)聽器
- 在application.properties中配置監(jiān)聽器
2.2 將監(jiān)聽器裝載入spring容器
// 裝載入spring容器中 @Slf4j @Component public class MyListener1 implements ApplicationListener<MyEvent> { @Override public void onApplicationEvent(MyEvent event) { // 這里可以自定義自己的方法 log.info(String.format("%s監(jiān)聽到事件源:%s.", MyListener1.class.getName(), event.toString())); } }
如果不加@Component注解加入Spring容器,也可以手動加入
@SpringBootApplication public class ListenerApplication { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(ListenerApplication.class, args); //裝載監(jiān)聽 context.addApplicationListener(new MyListener1()); } }
也可以通過配置文application.properties中配置監(jiān)聽器:context.listener.classes=com.listener.MyListener1
2.3 @EventListener注解實現(xiàn)事件監(jiān)聽
@Component @Slf4j public class MyListener2{ // 通過注解的方法 @EventListener(MyEvent.class) public void consumer(MyEvent msgEvent) { log.info(String.format("%s監(jiān)聽到事件源:%s.", MsgPublisher.class.getName(), msgEvent.toString())); } }
3、事件發(fā)布
前面是消費事件,消費的前提是有事件產(chǎn)生,在Spring中,發(fā)布事件主要需要借助ApplicationContext來實現(xiàn)
@Component @Slf4j public class MsgPublisher implements ApplicationContextAware { private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } // 發(fā)起事件通知 public void publish(String msg) { applicationContext.publishEvent(new MyEvent1(this, msg)); } // 通過注解的方法 @EventListener(MyEvent.class) public void consumer(MyEvent msgEvent) { log.info(String.format("%s監(jiān)聽到事件源:%s.", MsgPublisher.class.getName(), msgEvent.toString())); } /** * 這個只是測試,到時候spring直接調(diào)用即可 */ public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(MsgPublisher.class); MsgPublisher msgPublisher = context.getBean(MsgPublisher.class); msgPublisher.publish("hello world"); } }
到此這篇關(guān)于Spring事件監(jiān)聽基本原理與使用詳解的文章就介紹到這了,更多相關(guān)Spring事件監(jiān)聽內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Boot高級教程之使用Redis實現(xiàn)session共享
這篇文章主要為大家詳細介紹了Spring Boot高級教程之使用Redis實現(xiàn)session共享,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-10-10mybatis-plus 實現(xiàn)分頁查詢的示例代碼
本文介紹了在MyBatis-Plus中實現(xiàn)分頁查詢,包括引入依賴、配置分頁插件、使用分頁查詢以及在控制器中調(diào)用分頁查詢的方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-11-11IntelliJ IDEA安裝scala插件并創(chuàng)建scala工程的步驟詳細教程
這篇文章主要介紹了IntelliJ IDEA安裝scala插件并創(chuàng)建scala工程的步驟,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-07-07java創(chuàng)建二維碼并賦予url鏈接的功能實現(xiàn)
這篇文章給大家分享java創(chuàng)建二維碼并賦予url鏈接的功能實現(xiàn),需要獲取要賦值給二維碼的鏈接后綴,通過設(shè)置二維碼的訪問路徑等一系列操作,具體實現(xiàn)代碼跟隨小編一起看看吧2021-06-06spring boot 日志/頁面處理、實體類構(gòu)建、后臺管理功能的實現(xiàn)
這篇文章主要介紹了spring boot 日志/頁面處理、實體類構(gòu)建、后臺管理功能的實現(xiàn),本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-08-08