最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring監(jiān)聽(tīng)器之ApplicationListener原理及源碼深度解析

 更新時(shí)間:2026年04月21日 09:04:59   作者:林海靜  
本文介紹了Spring事件機(jī)制的原理理及源碼解析,重點(diǎn)了ContextRefreshedEvent和ContextClosededEvent事件;并詳細(xì)描了事件發(fā)布流程、事件多播器器的源碼執(zhí)行流程;以及容器中監(jiān)聽(tīng)器的管理;最后舉了一個(gè)自定義監(jiān)聽(tīng)器的例子以然示如何利用事件機(jī)制,感興趣的朋友一起看看吧

一、原理及源碼解析

事件:ContextRefreshedEvent、IOCTest_Ext$1[source=我發(fā)布的事件]、ContextClosedEvent;
 *  1)、ContextRefreshedEvent事件:
 *      1)、容器創(chuàng)建對(duì)象:refresh();
 *      2)、finishRefresh();容器刷新完成會(huì)發(fā)布ContextRefreshedEvent事件
 *  2)、自己發(fā)布事件;
 *  3)、容器關(guān)閉會(huì)發(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)建對(duì)象:refresh();
 *      2)、initApplicationEventMulticaster();初始化ApplicationEventMulticaster;
 *          1)、先去容器中找有沒(méi)有id=“applicationEventMulticaster”的組件;
 *          2)、如果沒(méi)有this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
 *              并且加入到容器中,我們就可以在其他組件要派發(fā)事件,自動(dòng)注入這個(gè)applicationEventMulticaster;
 *  
 *  【容器中有哪些監(jiān)聽(tīng)器】源碼執(zhí)行流程:
 *      1)、容器創(chuàng)建對(duì)象:refresh();
 *      2)、registerListeners();
 *          從容器中拿到所有的監(jiān)聽(tīng)器,把他們注冊(cè)到applicationEventMulticaster中;
 *          String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
 *          //將listener注冊(cè)到ApplicationEventMulticaster中
 *          getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
 *          
 *   SmartInitializingSingleton 原理:->afterSingletonsInstantiated();
 *           1)、ioc容器創(chuàng)建對(duì)象并refresh();
 *           2)、finishBeanFactoryInitialization(beanFactory);初始化剩下的單實(shí)例bean;
 *               1)、先創(chuàng)建所有的單實(shí)例bean;getBean();
 *               2)、獲取所有創(chuàng)建好的單實(shí)例bean,判斷是否是SmartInitializingSingleton類(lèi)型的;
 *                   如果是就調(diào)用afterSingletonsInstantiated();
 *         

二、實(shí)例

ApplicationListener:監(jiān)聽(tīng)容器中發(fā)布的事件。事件驅(qū)動(dòng)模型開(kāi)發(fā);
 *       public interface ApplicationListener<E extends ApplicationEvent>
 *         監(jiān)聽(tīng) ApplicationEvent 及其下面的子事件;
 * 
 *      步驟:
 *         1)、寫(xiě)一個(gè)監(jiān)聽(tīng)器(ApplicationListener實(shí)現(xiàn)類(lèi))來(lái)監(jiān)聽(tīng)某個(gè)事件(ApplicationEvent及其子類(lèi))
 *             @EventListener;
 *             原理:使用EventListenerMethodProcessor處理器來(lái)解析方法上的@EventListener;
 * 
 *         2)、把監(jiān)聽(tīng)器加入到容器;
 *         3)、只要容器中有相關(guān)事件的發(fā)布,我們就能監(jiān)聽(tīng)到這個(gè)事件;
 *                 ContextRefreshedEvent:容器刷新完成(所有bean都完全創(chuàng)建)會(huì)發(fā)布這個(gè)事件;
 *                 ContextClosedEvent:關(guān)閉容器會(huì)發(fā)布這個(gè)事件;
 *         4)、發(fā)布一個(gè)事件:
 *                 applicationContext.publishEvent();

1、自定義監(jiān)聽(tīng)器

定義MyApplicationListener 類(lèi)并實(shí)現(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注解來(lái)定義一個(gè)監(jiān)聽(tīng)器

注:@EventListener(classes={ApplicationEvent.class})中classes監(jiān)聽(tīng)的類(lèi)可以是多個(gè),以逗號(hào)分開(kāi)

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)聽(tīng)到的事件:"+event);
	}
}

2、定義配置類(lèi),加載IOC容器

@ComponentScan("com.atguigu.ext")
@Configuration
public class ExtConfig {
	@Bean
	public Blue blue(){
		return new Blue();
	}
}

3、測(cè)試

自定義發(fā)布事件使用了匿名內(nèi)部類(lè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é)果:

說(shuō)明:spring自己有自定義監(jiān)聽(tīng)器,如容器有刷新和關(guān)閉事件發(fā)布就會(huì)被監(jiān)聽(tīng)到;自己定義了監(jiān)聽(tīng)器并裝配到spring容器中,一旦有相關(guān)事件發(fā)布也可以被監(jiān)聽(tīng)到。

到此這篇關(guān)于Spring監(jiān)聽(tīng)器之ApplicationListener原理及源碼深度解析的文章就介紹到這了,更多相關(guān)Spring ApplicationListener原理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringCloud一個(gè)模塊調(diào)用另一個(gè)模塊的服務(wù)實(shí)現(xiàn)過(guò)程

    SpringCloud一個(gè)模塊調(diào)用另一個(gè)模塊的服務(wù)實(shí)現(xiàn)過(guò)程

    SpringCloud服務(wù)調(diào)用詳解與Hystrix熔斷機(jī)制介紹,通過(guò)創(chuàng)建接口和添加依賴(lài)實(shí)現(xiàn)不同模塊間的服務(wù)調(diào)用,并探討了Hystrix在處理容錯(cuò)和熔斷中的應(yīng)用
    2026-06-06
  • Java中的集合工具類(lèi)Collections詳解

    Java中的集合工具類(lèi)Collections詳解

    這篇文章主要介紹了Java中的集合工具類(lèi)Collections詳解,java.utils.Collections是集合工具類(lèi),用來(lái)對(duì)集合進(jìn)行操作,不是Collection集合的根接口,這個(gè)要區(qū)分開(kāi)來(lái),需要的朋友可以參考下
    2024-01-01
  • java 多態(tài)性詳解及簡(jiǎn)單實(shí)例

    java 多態(tài)性詳解及簡(jiǎn)單實(shí)例

    這篇文章主要介紹了java 多態(tài)性詳解及簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • Java程序?qū)崿F(xiàn)導(dǎo)出Excel的方法(支持IE低版本)

    Java程序?qū)崿F(xiàn)導(dǎo)出Excel的方法(支持IE低版本)

    下面小編就為大家?guī)?lái)一篇Java程序?qū)崿F(xiàn)導(dǎo)出Excel的方法(支持IE低版本)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-07-07
  • java垃圾回收之實(shí)現(xiàn)并行GC算法

    java垃圾回收之實(shí)現(xiàn)并行GC算法

    這篇文章主要為大家介紹了java垃圾回收之實(shí)現(xiàn)并行GC算法的詳細(xì)講解,讓我們看看并行垃圾收集器的GC日志長(zhǎng)什么樣,?從中我們可以得到哪些有用信息
    2022-01-01
  • Java List接口與Iterator接口及foreach循環(huán)使用解析

    Java List接口與Iterator接口及foreach循環(huán)使用解析

    這篇文章主要介紹了Java List接口與Iterator接口及foreach循環(huán),主要包括List接口與Iterator接口及foreach循環(huán)具體的使用方法和代碼,需要的朋友可以參考下
    2022-04-04
  • Java超詳細(xì)梳理IO流的使用方法上

    Java超詳細(xì)梳理IO流的使用方法上

    流(Stream)是指一連串的數(shù)據(jù)(字符或字節(jié)),是以先進(jìn)先出的方式發(fā)送信息的通道,數(shù)據(jù)源發(fā)送的數(shù)據(jù)經(jīng)過(guò)這個(gè)通道到達(dá)目的地,按流向區(qū)分為輸入流和輸出流
    2022-04-04
  • Springboot shiro認(rèn)證授權(quán)實(shí)現(xiàn)原理及實(shí)例

    Springboot shiro認(rèn)證授權(quán)實(shí)現(xiàn)原理及實(shí)例

    這篇文章主要介紹了Springboot shiro認(rèn)證授權(quán)實(shí)現(xiàn)原理及實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • resttemplate設(shè)置params的方法

    resttemplate設(shè)置params的方法

    RestTemplate設(shè)置請(qǐng)求參數(shù)的方式根據(jù)請(qǐng)求類(lèi)型(GET/POST)和參數(shù)形式(路徑參數(shù)、查詢(xún)參數(shù)、JSON請(qǐng)求體)有所不同,下面通過(guò)本文給大家介紹resttemplate設(shè)置params的方法,感興趣的朋友一起看看吧
    2025-04-04
  • jackson 實(shí)現(xiàn)null轉(zhuǎn)0 以及0轉(zhuǎn)null的示例代碼

    jackson 實(shí)現(xiàn)null轉(zhuǎn)0 以及0轉(zhuǎn)null的示例代碼

    這篇文章主要介紹了jackson 實(shí)現(xiàn)null轉(zhuǎn)0 以及0轉(zhuǎn)null的示例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-09

最新評(píng)論

阿坝县| 刚察县| 来安县| 桐乡市| 延长县| 响水县| 无为县| 华安县| 惠州市| 夏津县| 农安县| 宜宾市| 濉溪县| 六盘水市| 绥宁县| 苏尼特右旗| 宁南县| 嫩江县| 岑溪市| 元朗区| 乌拉特后旗| 夏邑县| 顺平县| 勐海县| 九台市| 襄垣县| 涟水县| 贡山| 东源县| 西城区| 房山区| 武陟县| 丰县| 工布江达县| 麻栗坡县| 崇信县| 上蔡县| 剑河县| 东宁县| 和静县| 静安区|