Spring中ApplicationListener的使用解析
背景
ApplicationContext事件機制是觀察者設計模式的實現(xiàn),通過ApplicationEvent類和ApplicationListener接口,可以實現(xiàn)ApplicationContext事件處理;
如果容器中存在ApplicationListener的Bean,當ApplicationContext調用publishEvent方法時,對應的Bean會被觸發(fā)。
spring內置事件
- ContextRefreshedEvent ApplicationContext 被初始化或刷新時,該事件被觸發(fā)。這也可以在 ConfigurableApplicationContext接口中使用 refresh() 方法來發(fā)生。此處的初始化是指:所有的Bean被成功裝載,后處理Bean被檢測并激活,所有Singleton Bean 被預實例化,ApplicationContext容器已就緒可用
- ContextStartedEvent 當使用 ConfigurableApplicationContext (ApplicationContext子接口)接口中的 start() 方法啟動 ApplicationContext 時,該事件被發(fā)布。你可以調查你的數(shù)據(jù)庫,或者你可以在接受到這個事件后重啟任何停止的應用程序。
- ContextStoppedEvent 當使用 ConfigurableApplicationContext 接口中的 stop() 停止 ApplicationContext 時,發(fā)布這個事件。你可以在接受到這個事件后做必要的清理的工作。
- ContextClosedEvent 當使用 ConfigurableApplicationContext 接口中的 close() 方法關閉 ApplicationContext 時,該事件被發(fā)布。一個已關閉的上下文到達生命周期末端;它不能被刷新或重啟。
- RequestHandledEvent 這是一個 web-specific 事件,告訴所有 bean HTTP 請求已經(jīng)被服務。只能應用于使用DispatcherServlet的Web應用。在使用Spring作為前端的MVC控制器時,當Spring處理用戶請求結束后,系統(tǒng)會自動觸發(fā)該事件。
同樣事件可以自定義、監(jiān)聽也可以自定義,完全根據(jù)自己的業(yè)務邏輯來處理。
ApplicationListener源碼
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
/**
* Handle an application event.
* @param event the event to respond to
*/
void onApplicationEvent(E event);
}ContextRefreshedEvent事件的監(jiān)聽
以Spring的內置事件ContextRefreshedEvent為例,當ApplicationContext被初始化或刷新時,會觸發(fā)ContextRefreshedEvent事件,下面我們就實現(xiàn)一個ApplicationListener來監(jiān)聽此事件的發(fā)生。
@Component
public class MyListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
System.out.println("容器中初始化Bean數(shù)量:" + event.getApplicationContext().getBeanDefinitionCount());
}
}啟動服務,可以看到

至此,便完成了一個事件及監(jiān)聽類的實現(xiàn)和實例化。
自定義事件及監(jiān)聽,以發(fā)送郵件為例
自定義郵件通知事件類:EmailEvent
package com.lw.coodytest.event;
import org.springframework.context.ApplicationEvent;
/**
* @Classname EmailEvent
* @Description 郵件通知事件
* @Author lw
* @Date 2019-12-20 11:05
*/
public class EmailEvent extends ApplicationEvent {
private String email;
private String content;
public EmailEvent(Object source){
super(source);
}
public EmailEvent(Object source, String email, String content){
super(source);
this.email = email;
this.content = content;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}自定義郵件通知監(jiān)聽類:EmailListener:
package com.lw.coodytest.event;
import org.springframework.context.ApplicationEvent;
/**
* @Classname EmailEvent
* @Description 郵件通知事件
* @Author lw
* @Date 2019-12-20 11:05
*/
public class EmailEvent extends ApplicationEvent {
private String email;
private String content;
public EmailEvent(Object source){
super(source);
}
public EmailEvent(Object source, String email, String content){
super(source);
this.email = email;
this.content = content;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}注意:onApplicationEvent方法的入?yún)?,必須是自定義的那個類型
單元測試類:
package com.lw.coodytest.junit;
import com.lw.coodytest.event.EmailEvent;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.context.WebApplicationContext;
/**
* @Classname ListenerTest
* @Description 監(jiān)聽測試類
* @Author lw
* @Date 2019-12-20 11:12
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class ListenerTest {
@Autowired
private WebApplicationContext webapplicationcontext;
@Test
public void testListener(){
EmailEvent emailEvent = new EmailEvent("object", "172572575@qq.com", "###listener");
webapplicationcontext.publishEvent(emailEvent);
}
}監(jiān)聽器通過@Component注解進行實例化,并在onApplicationEvent中打印相關信息: 執(zhí)行測試類,可以看到

至此,便完成了一個自定義事件及監(jiān)聽類的實現(xiàn)和實例化。
特別注意:不管是內置監(jiān)聽還是外部自定義監(jiān)聽一定要把實現(xiàn)ApplicationListener的類定義成一個bean才行,可以通過注解@Component或者在bean.xml中定義來實現(xiàn)。
也就是說通過注冊為bean,才能實現(xiàn)事件的綁定。
到此這篇關于Spring中ApplicationListener的使用解析的文章就介紹到這了,更多相關ApplicationListener的使用內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- Spring ApplicationListener監(jiān)聽器用法詳解
- Spring ApplicationListener的使用詳解
- Spring ApplicationListener源碼解析
- SpringBoot中ApplicationEvent和ApplicationListener用法小結
- SpringBoot ApplicationListener事件監(jiān)聽接口使用問題探究
- Spring事件監(jiān)聽器ApplicationListener源碼詳解
- SpringBoot中的ApplicationListener事件監(jiān)聽器使用詳解
- spring中ApplicationListener的使用小結
相關文章
sftp和ftp 根據(jù)配置遠程服務器地址下載文件到當前服務
這篇文章主要介紹了sftp和ftp 根據(jù)配置遠程服務器地址下載文件到當前服務的相關資料本文給大家介紹的非常詳細,具有參考借鑒價值,需要的朋友可以參考下2016-10-10
Javamelody監(jiān)控不到sql的問題(親測有效)??
JavaMelody是用來在QA和實際運行生產(chǎn)環(huán)境中監(jiān)控Java或Java?EE應用程序服務器的一個開源框架,這篇文章主要介紹了Javamelody監(jiān)控不到sql(親測有效)??,需要的朋友可以參考下2022-10-10
spring?bean標簽中的init-method和destroy-method詳解
這篇文章主要介紹了spring?bean標簽中的init-method和destroy-method,在很多項目中,經(jīng)常在xml配置文件中看到init-method 或者 destroy-method ,因此整理收集下,方便以后參考和學習,需要的朋友可以參考下2023-04-04
Springboot使用influxDB時序數(shù)據(jù)庫的實現(xiàn)
項目中需要存放大量設備日志,且需要對其進行簡單的數(shù)據(jù)分析,信息提取工作,所以本文就介紹一下Springboot使用influxDB時序數(shù)據(jù)庫,感興趣的可以了解一下2021-08-08
Java中實現(xiàn)Comparator接口和用法實例(簡明易懂)
這篇文章主要介紹了Java中實現(xiàn)Comparator接口和用法實例(簡明易懂),本文給出實現(xiàn)Comparator接口的實例和使用這個接口的代碼實例,需要的朋友可以參考下2015-05-05
java數(shù)據(jù)輸出打印流PrintStream和PrintWriter面試精講
這篇文章主要為大家介紹了java數(shù)據(jù)輸出打印流PrintStream和PrintWriter面試精講,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-10-10

