Spring監(jiān)聽器之ApplicationListener原理及源碼深度解析
一、原理及源碼解析
事件:ContextRefreshedEvent、IOCTest_Ext$1[source=我發(fā)布的事件]、ContextClosedEvent;
* 1)、ContextRefreshedEvent事件:
* 1)、容器創(chuàng)建對象:refresh();
* 2)、finishRefresh();容器刷新完成會發(fā)布ContextRefreshedEvent事件
* 2)、自己發(fā)布事件;
* 3)、容器關(guān)閉會發(fā)布ContextClosedEvent;
*
* 【事件發(fā)布流程】源碼執(zhí)行流程:
* 3)、publishEvent(new ContextRefreshedEvent(this));
* 1)、獲取事件的多播器(派發(fā)器):getApplicationEventMulticaster()
* 2)、multicastEvent派發(fā)事件:
* 3)、獲取到所有的ApplicationListener;
* for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
* 1)、如果有Executor,可以支持使用Executor進(jìn)行異步派發(fā);
* Executor executor = getTaskExecutor();
* 2)、否則,同步的方式直接執(zhí)行l(wèi)istener方法;invokeListener(listener, event);
* 拿到listener回調(diào)onApplicationEvent方法;
*
* 【事件多播器(派發(fā)器)】源碼執(zhí)行流程:
* 1)、容器創(chuàng)建對象:refresh();
* 2)、initApplicationEventMulticaster();初始化ApplicationEventMulticaster;
* 1)、先去容器中找有沒有id=“applicationEventMulticaster”的組件;
* 2)、如果沒有this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
* 并且加入到容器中,我們就可以在其他組件要派發(fā)事件,自動注入這個applicationEventMulticaster;
*
* 【容器中有哪些監(jiān)聽器】源碼執(zhí)行流程:
* 1)、容器創(chuàng)建對象:refresh();
* 2)、registerListeners();
* 從容器中拿到所有的監(jiān)聽器,把他們注冊到applicationEventMulticaster中;
* String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
* //將listener注冊到ApplicationEventMulticaster中
* getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
*
* SmartInitializingSingleton 原理:->afterSingletonsInstantiated();
* 1)、ioc容器創(chuàng)建對象并refresh();
* 2)、finishBeanFactoryInitialization(beanFactory);初始化剩下的單實例bean;
* 1)、先創(chuàng)建所有的單實例bean;getBean();
* 2)、獲取所有創(chuàng)建好的單實例bean,判斷是否是SmartInitializingSingleton類型的;
* 如果是就調(diào)用afterSingletonsInstantiated();
*
二、實例
ApplicationListener:監(jiān)聽容器中發(fā)布的事件。事件驅(qū)動模型開發(fā);
* public interface ApplicationListener<E extends ApplicationEvent>
* 監(jiān)聽 ApplicationEvent 及其下面的子事件;
*
* 步驟:
* 1)、寫一個監(jiān)聽器(ApplicationListener實現(xiàn)類)來監(jiān)聽某個事件(ApplicationEvent及其子類)
* @EventListener;
* 原理:使用EventListenerMethodProcessor處理器來解析方法上的@EventListener;
*
* 2)、把監(jiān)聽器加入到容器;
* 3)、只要容器中有相關(guān)事件的發(fā)布,我們就能監(jiān)聽到這個事件;
* ContextRefreshedEvent:容器刷新完成(所有bean都完全創(chuàng)建)會發(fā)布這個事件;
* ContextClosedEvent:關(guān)閉容器會發(fā)布這個事件;
* 4)、發(fā)布一個事件:
* applicationContext.publishEvent();
1、自定義監(jiān)聽器
定義MyApplicationListener 類并實現(xiàn)ApplicationListener<ApplicationEvent>接口
用@Component裝配到Spring容器中
package com.atguigu.ext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
//當(dāng)容器中發(fā)布此事件以后,方法觸發(fā)
@Override
public void onApplicationEvent(ApplicationEvent event) {
// TODO Auto-generated method stub
System.out.println("收到事件:"+event);
}
}或者使用@EventListener注解來定義一個監(jiān)聽器
注:@EventListener(classes={ApplicationEvent.class})中classes監(jiān)聽的類可以是多個,以逗號分開
package com.atguigu.ext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@EventListener(classes={ApplicationEvent.class})
public void listen(ApplicationEvent event){
System.out.println("UserService。。監(jiān)聽到的事件:"+event);
}
}2、定義配置類,加載IOC容器
@ComponentScan("com.atguigu.ext")
@Configuration
public class ExtConfig {
@Bean
public Blue blue(){
return new Blue();
}
}3、測試
自定義發(fā)布事件使用了匿名內(nèi)部類
package com.atguigu.test;
import org.junit.Test;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.atguigu.ext.ExtConfig;
public class IOCTest_Ext {
@Test
public void test01(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class);
//發(fā)布事件;
applicationContext.publishEvent(new ApplicationEvent(new String("我發(fā)布的事件")) {
});
applicationContext.close();
}
}結(jié)果:


說明:spring自己有自定義監(jiān)聽器,如容器有刷新和關(guān)閉事件發(fā)布就會被監(jiān)聽到;自己定義了監(jiān)聽器并裝配到spring容器中,一旦有相關(guān)事件發(fā)布也可以被監(jiān)聽到。
到此這篇關(guān)于Spring監(jiān)聽器之ApplicationListener原理及源碼深度解析的文章就介紹到這了,更多相關(guān)Spring ApplicationListener原理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Spring事件監(jiān)聽器ApplicationListener的使用與原理分析
- Spring中ApplicationListener的使用解析
- SpringBoot中的ApplicationListener事件監(jiān)聽器使用詳解
- SpringBoot中ApplicationEvent和ApplicationListener用法小結(jié)
- Spring ApplicationListener的使用詳解
- SpringMVC事件監(jiān)聽ApplicationListener實例解析
- Spring ApplicationListener監(jiān)聽器用法詳解
- springBoot的事件機制GenericApplicationListener用法解析
相關(guān)文章
SpringCloud一個模塊調(diào)用另一個模塊的服務(wù)實現(xiàn)過程
SpringCloud服務(wù)調(diào)用詳解與Hystrix熔斷機制介紹,通過創(chuàng)建接口和添加依賴實現(xiàn)不同模塊間的服務(wù)調(diào)用,并探討了Hystrix在處理容錯和熔斷中的應(yīng)用2026-06-06
Java程序?qū)崿F(xiàn)導(dǎo)出Excel的方法(支持IE低版本)
下面小編就為大家?guī)硪黄狫ava程序?qū)崿F(xiàn)導(dǎo)出Excel的方法(支持IE低版本)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-07-07
Java List接口與Iterator接口及foreach循環(huán)使用解析
這篇文章主要介紹了Java List接口與Iterator接口及foreach循環(huán),主要包括List接口與Iterator接口及foreach循環(huán)具體的使用方法和代碼,需要的朋友可以參考下2022-04-04
Springboot shiro認(rèn)證授權(quán)實現(xiàn)原理及實例
這篇文章主要介紹了Springboot shiro認(rèn)證授權(quán)實現(xiàn)原理及實例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-06-06
jackson 實現(xiàn)null轉(zhuǎn)0 以及0轉(zhuǎn)null的示例代碼
這篇文章主要介紹了jackson 實現(xiàn)null轉(zhuǎn)0 以及0轉(zhuǎn)null的示例代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09

