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

Spring中的refreshContext源碼分析

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

前言

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

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

refreshContext()

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

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

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

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

prepareBeanFactory()

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		//添加了一個BeanPostProcessor實例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);
		//指定特定依賴的返回結果
		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.
		//添加了一個BeanPostProcessor實例ApplicationListenerDetector
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
		...
	}

老辦法 ,逐一分析。

第一步,添加了一個BeanPostProcessor實例ApplicationContextAwareProcessor

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

指定特定依賴的返回結果添加了一個BeanPostProcessor實例ApplicationListenerDetector

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

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

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

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

invokeBeanFactoryPostProcessors()

喚醒所有的BeanFactoryPostProcessor實例 ,這個與下面的registerBeanPostProcessor將會以獨立的章節(jié)來分析(原因還是那個原因。。。 里面的內容有點多)。

registerBeanPostProcessor()

將BeanPostProcessor實例注冊進來

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ā)送默認的事件集
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (earlyEventsToProcess != null) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}

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

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

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

總結

  1. 準備BeanFacotry
  2. BeanFacotry準備完畢
  3. 對BeanFacotryPostProcessor進行喚醒(因為BeanFactory準備完畢了嘛)
  4. 注冊BeanPostProcessor(因為接下來我們要實例化Bean嘛)
  5. 對單例Bean進行實例化

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

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

相關文章

最新評論

岳阳县| 景泰县| 高青县| 临夏县| 开封县| 藁城市| 上栗县| 长阳| 正安县| 托克逊县| 武定县| 江阴市| 交口县| 樟树市| 尼勒克县| 郧西县| 开江县| 乾安县| 临泉县| 金溪县| 古田县| 祁连县| 大安市| 咸丰县| 嘉义市| 遂平县| 凯里市| 惠来县| 馆陶县| 神木县| 濮阳县| 易门县| 巨野县| 湖北省| 霍邱县| 永清县| 宁阳县| 马山县| 洮南市| 中卫市| 昌江|