Spring事件監(jiān)聽基本原理與使用詳解
一、簡介
1、Spring事件監(jiān)聽基本原理
Spring的事件監(jiān)聽機制和發(fā)布訂閱機制是很相似的:發(fā)布了一個事件后,監(jiān)聽該類型事件的所有監(jiān)聽器會觸發(fā)相應的處理邏輯。
正如Spring官方文檔上所說的,整個上就是一個觀察者的模式。那么,我們不妨猜測下,Spring是如何來實現(xiàn)事件發(fā)布監(jiān)聽的:底層使用一個集合存儲了所有的監(jiān)聽器,當發(fā)布了一個事件后,遍歷事件監(jiān)聽器集合,然后過濾符合事件類型的監(jiān)聽器,最后觸發(fā)相應的事件處理邏輯。
2、Spring中事件監(jiān)聽的相關規(guī)范
在Spring中,事件監(jiān)聽機制主要涉及到了一下幾個關鍵的規(guī)范(抽象類及接口):ApplicationEvent、ApplicationListener、ApplicationEventPublisher
- ApplicationEvent: Spring的事件是符合jdk的規(guī)范的,這個抽象類繼承了jdk內置的事件規(guī)范類EventObject(即jdk建議所有的事件都繼承EventObject這個類)。ApplicationEvent是Spring家的事件規(guī)范。所以我們在自定義事件的時候,可以繼承與ApplicationEvent,比如,Spring家自己關于容器上下文事件就又定義了一個容器上下文的時間規(guī)范ApplicationContextEvent,它同樣是繼承于ApplicationEvent的,只不過擴充了獲取發(fā)出事件容器的方法;今后,我們同樣可以在繼承于ApplicationEvent的基礎上定義自己的事件規(guī)范。
- ApplicationListener:這是一個函數式接口,同樣時事件監(jiān)聽器的規(guī)范,當監(jiān)聽到自己監(jiān)聽的事件類型時就會調用onApplicationEvent方法來執(zhí)行監(jiān)聽邏輯
- ApplicationEventPublisher:這同樣是一個函數式接口,定義了事件發(fā)布的規(guī)范,任何的事件發(fā)布器ApplicationEventPublisher都是通過調用publishEvent來進行事件的發(fā)布
二、Spring事件監(jiān)聽器的使用
1、自定義事件創(chuàng)建
在Spring中,所有的事件需要繼承自ApplicationEvent,自定義事件的不同可以監(jiān)聽多個,一個最基礎的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ā)布
前面是消費事件,消費的前提是有事件產生,在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直接調用即可
*/
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(MsgPublisher.class);
MsgPublisher msgPublisher = context.getBean(MsgPublisher.class);
msgPublisher.publish("hello world");
}
}到此這篇關于Spring事件監(jiān)聽基本原理與使用詳解的文章就介紹到這了,更多相關Spring事件監(jiān)聽內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Mybatis-Plus save和saveBatch方法忽略自增主鍵詳解
Mybatis-Plus在從3.4.0升級到3.5.6后,save和saveBatch方法在處理自增主鍵時會出現(xiàn)主鍵沖突的問題,這是因為3.5.6版本中增加了`ignoreAutoIncrementColumn`屬性,默認值為false,導致在生成SQL語句時忽略了自增主鍵,解決方法是手動設置主鍵值2025-12-12
Spring MVC實現(xiàn)mysql數據庫增刪改查完整實例
這篇文章主要介紹了Spring MVC實現(xiàn)mysql數據庫增刪改查完整實例,從創(chuàng)建一個web項目開始,分享了項目結構以及具體Java代碼和前端頁面等相關內容,具有一定借鑒價值,需要的朋友可以了解下。2017-12-12
SpringBoot3集成iText實現(xiàn)PDF導出功能
不知道小伙伴們在項目中有沒有遇到過導出 PDF 的需求,小編在之前的 tienchin 項目中有一個合同導出的功能,需要將文檔導出為PDF,將文檔導出為 PDF 有很多方案,不同方案的優(yōu)缺點也各不相同,今天小編就和大家演示一個,感興趣的小伙伴跟著小編一起來看看吧2024-10-10
SpringBoot里使用Servlet進行請求的實現(xiàn)示例
這篇文章主要介紹了SpringBoot里使用Servlet進行請求的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-01-01
Java中的數組流ByteArrayOutputStream用法
Java中的ByteArrayOutputStream是java.io包中的一個類,用于在內存中創(chuàng)建字節(jié)數組緩沖區(qū),支持動態(tài)擴展,它繼承自OutputStream,允許以字節(jié)形式寫入數據,無需與外部設備交互,常用方法包括write()、toByteArray()、toString()等2024-09-09

