Spring中ApplicationListener的使用解析
背景
ApplicationContext事件機(jī)制是觀察者設(shè)計(jì)模式的實(shí)現(xiàn),通過(guò)ApplicationEvent類和ApplicationListener接口,可以實(shí)現(xiàn)ApplicationContext事件處理;
如果容器中存在ApplicationListener的Bean,當(dāng)ApplicationContext調(diào)用publishEvent方法時(shí),對(duì)應(yīng)的Bean會(huì)被觸發(fā)。
spring內(nèi)置事件
- ContextRefreshedEvent ApplicationContext 被初始化或刷新時(shí),該事件被觸發(fā)。這也可以在 ConfigurableApplicationContext接口中使用 refresh() 方法來(lái)發(fā)生。此處的初始化是指:所有的Bean被成功裝載,后處理Bean被檢測(cè)并激活,所有Singleton Bean 被預(yù)實(shí)例化,ApplicationContext容器已就緒可用
- ContextStartedEvent 當(dāng)使用 ConfigurableApplicationContext (ApplicationContext子接口)接口中的 start() 方法啟動(dòng) ApplicationContext 時(shí),該事件被發(fā)布。你可以調(diào)查你的數(shù)據(jù)庫(kù),或者你可以在接受到這個(gè)事件后重啟任何停止的應(yīng)用程序。
- ContextStoppedEvent 當(dāng)使用 ConfigurableApplicationContext 接口中的 stop() 停止 ApplicationContext 時(shí),發(fā)布這個(gè)事件。你可以在接受到這個(gè)事件后做必要的清理的工作。
- ContextClosedEvent 當(dāng)使用 ConfigurableApplicationContext 接口中的 close() 方法關(guān)閉 ApplicationContext 時(shí),該事件被發(fā)布。一個(gè)已關(guān)閉的上下文到達(dá)生命周期末端;它不能被刷新或重啟。
- RequestHandledEvent 這是一個(gè) web-specific 事件,告訴所有 bean HTTP 請(qǐng)求已經(jīng)被服務(wù)。只能應(yīng)用于使用DispatcherServlet的Web應(yīng)用。在使用Spring作為前端的MVC控制器時(shí),當(dāng)Spring處理用戶請(qǐng)求結(jié)束后,系統(tǒng)會(huì)自動(dòng)觸發(fā)該事件。
同樣事件可以自定義、監(jiān)聽也可以自定義,完全根據(jù)自己的業(yè)務(wù)邏輯來(lái)處理。
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的內(nèi)置事件ContextRefreshedEvent為例,當(dāng)ApplicationContext被初始化或刷新時(shí),會(huì)觸發(fā)ContextRefreshedEvent事件,下面我們就實(shí)現(xiàn)一個(gè)ApplicationListener來(lái)監(jiān)聽此事件的發(fā)生。
@Component public class MyListener implements ApplicationListener<ContextRefreshedEvent> { @Override public void onApplicationEvent(ContextRefreshedEvent event) { System.out.println("容器中初始化Bean數(shù)量:" + event.getApplicationContext().getBeanDefinitionCount()); } }
啟動(dòng)服務(wù),可以看到
至此,便完成了一個(gè)事件及監(jiān)聽類的實(shí)現(xiàn)和實(shí)例化。
自定義事件及監(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)?,必須是自定義的那個(gè)類型
單元測(cè)試類:
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)聽測(cè)試類 * @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)聽器通過(guò)@Component注解進(jìn)行實(shí)例化,并在onApplicationEvent中打印相關(guān)信息: 執(zhí)行測(cè)試類,可以看到
至此,便完成了一個(gè)自定義事件及監(jiān)聽類的實(shí)現(xiàn)和實(shí)例化。
特別注意:不管是內(nèi)置監(jiān)聽還是外部自定義監(jiān)聽一定要把實(shí)現(xiàn)ApplicationListener的類定義成一個(gè)bean才行,可以通過(guò)注解@Component或者在bean.xml中定義來(lái)實(shí)現(xiàn)。
也就是說(shuō)通過(guò)注冊(cè)為bean,才能實(shí)現(xiàn)事件的綁定。
到此這篇關(guān)于Spring中ApplicationListener的使用解析的文章就介紹到這了,更多相關(guān)ApplicationListener的使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Spring ApplicationListener監(jiān)聽器用法詳解
- Spring ApplicationListener的使用詳解
- Spring ApplicationListener源碼解析
- SpringBoot中ApplicationEvent和ApplicationListener用法小結(jié)
- SpringBoot ApplicationListener事件監(jiān)聽接口使用問(wèn)題探究
- Spring事件監(jiān)聽器ApplicationListener源碼詳解
- SpringBoot中的ApplicationListener事件監(jiān)聽器使用詳解
- spring中ApplicationListener的使用小結(jié)
相關(guān)文章
sftp和ftp 根據(jù)配置遠(yuǎn)程服務(wù)器地址下載文件到當(dāng)前服務(wù)
這篇文章主要介紹了sftp和ftp 根據(jù)配置遠(yuǎn)程服務(wù)器地址下載文件到當(dāng)前服務(wù)的相關(guān)資料本文給大家介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-10-10Javamelody監(jiān)控不到sql的問(wèn)題(親測(cè)有效)??
JavaMelody是用來(lái)在QA和實(shí)際運(yùn)行生產(chǎn)環(huán)境中監(jiān)控Java或Java?EE應(yīng)用程序服務(wù)器的一個(gè)開源框架,這篇文章主要介紹了Javamelody監(jiān)控不到sql(親測(cè)有效)??,需要的朋友可以參考下2022-10-10MyBatis?resultMap?id標(biāo)簽的錯(cuò)誤使用方式
這篇文章主要介紹了MyBatis?resultMap?id標(biāo)簽的錯(cuò)誤使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01spring?bean標(biāo)簽中的init-method和destroy-method詳解
這篇文章主要介紹了spring?bean標(biāo)簽中的init-method和destroy-method,在很多項(xiàng)目中,經(jīng)常在xml配置文件中看到init-method 或者 destroy-method ,因此整理收集下,方便以后參考和學(xué)習(xí),需要的朋友可以參考下2023-04-04Springboot使用influxDB時(shí)序數(shù)據(jù)庫(kù)的實(shí)現(xiàn)
項(xiàng)目中需要存放大量設(shè)備日志,且需要對(duì)其進(jìn)行簡(jiǎn)單的數(shù)據(jù)分析,信息提取工作,所以本文就介紹一下Springboot使用influxDB時(shí)序數(shù)據(jù)庫(kù),感興趣的可以了解一下2021-08-08Java中將異步調(diào)用轉(zhuǎn)為同步的五種實(shí)現(xiàn)方法
本文介紹了將異步調(diào)用轉(zhuǎn)為同步阻塞模式的五種方法:wait/notify、ReentrantLock+Condition、Future、CountDownLatch和CyclicBarrier,每種方法都有其適用場(chǎng)景和核心機(jī)制,可以根據(jù)具體需求選擇合適的方法,需要的朋友可以參考下2025-02-02Java中實(shí)現(xiàn)Comparator接口和用法實(shí)例(簡(jiǎn)明易懂)
這篇文章主要介紹了Java中實(shí)現(xiàn)Comparator接口和用法實(shí)例(簡(jiǎn)明易懂),本文給出實(shí)現(xiàn)Comparator接口的實(shí)例和使用這個(gè)接口的代碼實(shí)例,需要的朋友可以參考下2015-05-05java數(shù)據(jù)輸出打印流PrintStream和PrintWriter面試精講
這篇文章主要為大家介紹了java數(shù)據(jù)輸出打印流PrintStream和PrintWriter面試精講,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10