欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring中的refreshContext源碼分析

 更新時(shí)間:2023年12月31日 09:22:17   作者:唐芬奇  
這篇文章主要介紹了Spring中的refreshContext源碼分析,在SpringBoot啟動(dòng)流程中,主要的兩個(gè)階段是初始化SpringApplication對象以及SpringApplication.run方法執(zhí)行的內(nèi)容,今天主要細(xì)講的是SpringApplication.run中的刷新容器refreshContext方法,需要的朋友可以參考下

前言

在SpringBoot啟動(dòng)流程中,主要的兩個(gè)階段是初始化SpringApplication對象以及SpringApplication.run方法執(zhí)行的內(nèi)容

今天主要細(xì)講的是SpringApplication.run中的刷新容器refreshContext方法

refreshContext()

還是老辦法,先梳理它的大體流程,將不太重要的舍去。

@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			...
			// Prepare the bean factory for use in this context.
			//設(shè)置beanFacotry 和加載一些特殊bean的處理類,
			prepareBeanFactory(beanFactory);
				// 一些web項(xiàng)目的bean處理類
				postProcessBeanFactory(beanFactory);
				// Invoke factory processors registered as beans in the context.
				//重要,喚醒 BeanFactoryPostProcessor的實(shí)現(xiàn)類
				invokeBeanFactoryPostProcessors(beanFactory);
				...
				// Register bean processors that intercept bean creation.
				//重要,將BeanPostProcessor的bean定義注冊進(jìn)來
				registerBeanPostProcessors(beanFactory);
				...
				// Initialize event multicaster for this context.
				//再次創(chuàng)建一個(gè)廣播器
				initApplicationEventMulticaster();
				...
				// Check for listener beans and register them.
				//注冊listener到上述的心廣播器中
				registerListeners();
				// Instantiate all remaining (non-lazy-init) singletons.
				//重要,創(chuàng)建單例bean
				finishBeanFactoryInitialization(beanFactory);
				...
		}
	}

那么整體上就分為一下幾步

  1. 對beanFacotry進(jìn)行設(shè)置
  2. 對benFactory在做一些定制處理(比如加載一些web容器對bean的處理類)
  3. 喚醒beanFactoryPostProcessor的一些列實(shí)現(xiàn)類
  4. 創(chuàng)建一個(gè)新廣播器
  5. 將Listener加入到這個(gè)新廣播器中(注意,這的Listener將會(huì)比我們上一篇所說的多的多,至于原因 在喚醒那一步里面)
  6. 將所有找到的單例類,都創(chuàng)建處理(這步內(nèi)容也比較多,對于加載Bean的分析 將新啟一篇文章進(jìn)行說明)

prepareBeanFactory()

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		//添加了一個(gè)BeanPostProcessor實(shí)例ApplicationContextAwareProcessor
		// Configure the bean factory with context callbacks.
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
		//指定特定依賴的返回結(jié)果
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);
		// Register early post-processor for detecting inner beans as ApplicationListeners.
		//添加了一個(gè)BeanPostProcessor實(shí)例ApplicationListenerDetector
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
		...
	}

老辦法 ,逐一分析。

第一步,添加了一個(gè)BeanPostProcessor實(shí)例ApplicationContextAwareProcessor

  	ApplicationContextAwareProcessor //這個(gè)bean處理器就是在實(shí)現(xiàn)了
 		EnvironmentAware.class
 		EmbeddedValueResolverAware.class
 		ResourceLoaderAware.class
 		ApplicationEventPublisherAware.class
 		MessageSourceAware.class
 		ApplicationContextAware.class
 		//的類實(shí)例化之前喚醒對應(yīng)的接口方法

指定特定依賴的返回結(jié)果添加了一個(gè)BeanPostProcessor實(shí)例ApplicationListenerDetector

這個(gè)實(shí)例主要是檢查bean是否實(shí)現(xiàn)了ApplicationListener,如果實(shí)現(xiàn)了就將它添加到監(jiān)聽器集合中

前面我們說了也可以通過spring.factories這個(gè)文件添加ApplicationListenr

這里又提供了一種方式,但是這種通過ApplicationListenerDetector來加載的方式 會(huì)讓listener丟失一部分事件(因?yàn)樵跊]有加載Bean之前還有很多事件),如果需要監(jiān)聽非常前面的事件,還是要通過spring.factories這個(gè)文件添加

這里都是講處理類加載進(jìn)來,并沒有執(zhí)行對應(yīng)方法。真正訪問還在后面,前面只是準(zhǔn)備階段

invokeBeanFactoryPostProcessors()

喚醒所有的BeanFactoryPostProcessor實(shí)例 ,這個(gè)與下面的registerBeanPostProcessor將會(huì)以獨(dú)立的章節(jié)來分析(原因還是那個(gè)原因。。。 里面的內(nèi)容有點(diǎn)多)。

registerBeanPostProcessor()

將BeanPostProcessor實(shí)例注冊進(jìn)來

registerListeners()

protected void registerListeners() {
		// Register statically specified listeners first
		//加載老的listener
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			getApplicationEventMulticaster().addApplicationListener(listener);
		}
		//加載新的listenner
		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let post-processors apply to them!
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}
		// Publish early application events now that we finally have a multicaster...
		//發(fā)送默認(rèn)的事件集
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (earlyEventsToProcess != null) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}

這一步就是將listener注冊到新的廣播器中,分步走。

  • 加載老的listener,也就是我們最開始通過spring.factories加載進(jìn)來的監(jiān)聽器
  • 加載通過ApplicationListenerDetector注冊進(jìn)來的監(jiān)聽器
  • 發(fā)送默認(rèn)事件(就是表明這個(gè)時(shí)間節(jié)點(diǎn)的事件)到監(jiān)聽器中

完成bean的初始化,這個(gè)會(huì)單獨(dú)形成一個(gè)章節(jié),與getBean流程一起講解

總結(jié)

  1. 準(zhǔn)備BeanFacotry
  2. BeanFacotry準(zhǔn)備完畢
  3. 對BeanFacotryPostProcessor進(jìn)行喚醒(因?yàn)锽eanFactory準(zhǔn)備完畢了嘛)
  4. 注冊BeanPostProcessor(因?yàn)榻酉聛砦覀円獙?shí)例化Bean嘛)
  5. 對單例Bean進(jìn)行實(shí)例化

你看,邏輯清晰,前后有因果,一下就把整體流程給理順了,而且出乎意料的合理。

到此這篇關(guān)于Spring中的refreshContext源碼分析的文章就介紹到這了,更多相關(guān)refreshContext源碼內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java Lambda 表達(dá)式詳解及示例代碼

    Java Lambda 表達(dá)式詳解及示例代碼

    本文主要介紹Java Lambda 表達(dá)式的知識(shí),這里整理了相關(guān)資料,JavaLambda 是Java8 引入的新功能,有興趣的小伙伴可以參考下
    2016-09-09
  • Spring Hystrix熔斷報(bào)警原理圖例解析

    Spring Hystrix熔斷報(bào)警原理圖例解析

    這篇文章主要介紹了Spring Hystrix熔斷報(bào)警原理圖例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • java時(shí)間相關(guān)處理小結(jié)

    java時(shí)間相關(guān)處理小結(jié)

    這篇文章介紹了java時(shí)間相關(guān)處理,有需要的朋友可以參考一下
    2013-11-11
  • Spring Boot插件spring tool suite安裝及使用詳解

    Spring Boot插件spring tool suite安裝及使用詳解

    這篇文章主要介紹了Spring Boot插件spring tool suite安裝及使用詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Java中的浮點(diǎn)數(shù)分析

    Java中的浮點(diǎn)數(shù)分析

    Java中的浮點(diǎn)數(shù)分析...
    2006-12-12
  • Mybatis中的mapper模糊查詢語句LIKE

    Mybatis中的mapper模糊查詢語句LIKE

    這篇文章主要介紹了Mybatis中的mapper模糊查詢語句LIKE,具有很好的參考價(jià)值,希望對大家有所幫助。
    2021-12-12
  • ES結(jié)合java代碼聚合查詢詳細(xì)示例

    ES結(jié)合java代碼聚合查詢詳細(xì)示例

    es查詢有一個(gè)很常用的一種叫聚合查詢,相當(dāng)于mysql中的分組group by 后拿各組數(shù)量進(jìn)行統(tǒng)計(jì),實(shí)現(xiàn)起來也是很簡單,下面這篇文章主要給大家介紹了關(guān)于ES結(jié)合java代碼聚合查詢的相關(guān)資料,需要的朋友可以參考下
    2023-05-05
  • springboot+mybatis plus實(shí)現(xiàn)樹形結(jié)構(gòu)查詢

    springboot+mybatis plus實(shí)現(xiàn)樹形結(jié)構(gòu)查詢

    實(shí)際開發(fā)過程中經(jīng)常需要查詢節(jié)點(diǎn)樹,根據(jù)指定節(jié)點(diǎn)獲取子節(jié)點(diǎn)列表,本文主要介紹了springboot+mybatis plus實(shí)現(xiàn)樹形結(jié)構(gòu)查詢,感興趣的可以了解一下
    2021-07-07
  • java類比C++的STL庫詳解

    java類比C++的STL庫詳解

    這篇文章主要介紹了java類比C++的STL庫詳解,標(biāo)準(zhǔn)模板庫,是C++標(biāo)準(zhǔn)庫的重要組成部分,中文可譯為標(biāo)準(zhǔn)模板庫或者泛型庫,其包含有大量的模板類和模板函數(shù),STL 是一些容器、算法和其他一些組件的集合,需要的朋友可以參考下
    2023-08-08
  • Java實(shí)現(xiàn)快速排序算法的完整示例

    Java實(shí)現(xiàn)快速排序算法的完整示例

    這篇文章主要給大家介紹了關(guān)于Java實(shí)現(xiàn)快速排序算法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12

最新評論