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

Spring中的refreshContext源碼分析

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

前言

在SpringBoot啟動(dòng)流程中,主要的兩個(gè)階段是初始化SpringApplication對(duì)象以及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的處理類(lèi),
			prepareBeanFactory(beanFactory);
				// 一些web項(xiàng)目的bean處理類(lèi)
				postProcessBeanFactory(beanFactory);
				// Invoke factory processors registered as beans in the context.
				//重要,喚醒 BeanFactoryPostProcessor的實(shí)現(xiàn)類(lèi)
				invokeBeanFactoryPostProcessors(beanFactory);
				...
				// Register bean processors that intercept bean creation.
				//重要,將BeanPostProcessor的bean定義注冊(cè)進(jìn)來(lái)
				registerBeanPostProcessors(beanFactory);
				...
				// Initialize event multicaster for this context.
				//再次創(chuàng)建一個(gè)廣播器
				initApplicationEventMulticaster();
				...
				// Check for listener beans and register them.
				//注冊(cè)listener到上述的心廣播器中
				registerListeners();
				// Instantiate all remaining (non-lazy-init) singletons.
				//重要,創(chuàng)建單例bean
				finishBeanFactoryInitialization(beanFactory);
				...
		}
	}

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

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

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
 		//的類(lèi)實(shí)例化之前喚醒對(duì)應(yīng)的接口方法

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

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

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

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

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

invokeBeanFactoryPostProcessors()

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

registerBeanPostProcessor()

將BeanPostProcessor實(shí)例注冊(cè)進(jìn)來(lái)

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注冊(cè)到新的廣播器中,分步走。

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

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

總結(jié)

  1. 準(zhǔn)備BeanFacotry
  2. BeanFacotry準(zhǔn)備完畢
  3. 對(duì)BeanFacotryPostProcessor進(jìn)行喚醒(因?yàn)锽eanFactory準(zhǔn)備完畢了嘛)
  4. 注冊(cè)BeanPostProcessor(因?yàn)榻酉聛?lái)我們要實(shí)例化Bean嘛)
  5. 對(duì)單例Bean進(jìn)行實(shí)例化

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

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

相關(guān)文章

最新評(píng)論

台中市| 商河县| 绥阳县| 运城市| 元朗区| 罗平县| 漳平市| 泊头市| 安福县| 龙胜| 泰安市| 贵州省| 同心县| 塘沽区| 罗田县| 兰坪| 曲靖市| 深水埗区| 平南县| 温州市| 遂溪县| 三台县| 永福县| 句容市| 龙江县| 涡阳县| 平陆县| 毕节市| 吉水县| 大同市| 舟曲县| 双桥区| 资中县| 兴化市| 九龙县| 长泰县| 阿拉善右旗| 大宁县| 文昌市| 临洮县| 阿克苏市|