Spring應(yīng)用上下文生命周期
點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”
優(yōu)質(zhì)文章,第一時(shí)間送達(dá)
? 作者?|? Gouden
來(lái)源 |? urlify.cn/QrYzia
76套java從入門到精通實(shí)戰(zhàn)課程分享
Spring應(yīng)用上下文生命周期整體分成四個(gè)階段
ConfigurableApplicationContext#refresh,加載或者刷新持久化配置
ConfigurableApplicationContext#start,啟動(dòng)應(yīng)用上下文
ConfigurableApplicationContext#stop,停止應(yīng)用上下文
ConfigurableApplicationContext#close,關(guān)閉應(yīng)用上下文,釋放鎖定資源
實(shí)際上refresh執(zhí)行完成后Spring應(yīng)用上下文從廣義上來(lái)說(shuō)已經(jīng)啟動(dòng)了,start回調(diào)用LifeCycleProcessors的start方法,可以理解refresh處理Spring應(yīng)用上下文啟動(dòng)需要的東西,start相當(dāng)于是一個(gè)擴(kuò)展,close和stop是和refresh和close類似的逆向操作。
因此Spring應(yīng)用上下文生命周期重頭戲是refresh和close兩個(gè)方法對(duì)應(yīng)的實(shí)現(xiàn)。
refresh-刷新應(yīng)用上下文
整個(gè)refresh階段代碼如下所示:


從代碼可以看出,refresh整體分為以下幾個(gè)階段:
準(zhǔn)備刷新階段: prepareRefresh
BeanFactory創(chuàng)建階段: obtainFreshBeanFactory
BeanFactory準(zhǔn)備階段: prepareBeanFactory
BeanFactory后置處理階段: postProcessBeanFactory、invokeBeanFactoryPostProcessors
BeanFactory注冊(cè)BeanPostProcessor階段: registerBeanPostProcessors
初始化內(nèi)建Bean: initMessageSource、initApplicationEventMulticaster
Spring應(yīng)用上下文刷新階段: onRefresh
Spring事件監(jiān)聽器注冊(cè)階段: registerListener
BeanFactory初始化完成階段: finishBeanFactoryInitialization
Spring應(yīng)用上下文刷新完成階段: finishRefresh
準(zhǔn)備刷新階段
prepareRefresh方法注釋如下所示,可以看出,這個(gè)方法主要做了三件事來(lái)準(zhǔn)備上下文刷新:
設(shè)置啟動(dòng)時(shí)間
設(shè)置激活標(biāo)
執(zhí)行任何初始化屬性來(lái)源

protected?void?prepareRefresh()?{
????????//設(shè)置啟動(dòng)時(shí)間、激活標(biāo)
????????this.startupDate?=?System.currentTimeMillis();
????????this.closed.set(false);
????????this.active.set(true);
????????if?(logger.isDebugEnabled())?{
????????????if?(logger.isTraceEnabled())?{
????????????????logger.trace("Refreshing?"?+?this);
????????????}
????????????else?{
????????????????logger.debug("Refreshing?"?+?getDisplayName());
????????????}
????????}
????????//初始化屬性源,擴(kuò)展用
????????initPropertySources();
????????//校驗(yàn)必要屬性
????????getEnvironment().validateRequiredProperties();
????????//創(chuàng)建存儲(chǔ)早期applicationListeners容器
????????if?(this.earlyApplicationListeners?==?null)?{
????????????this.earlyApplicationListeners?=?new?LinkedHashSet<>(this.applicationListeners);
????????}
????????else?{
????????????this.applicationListeners.clear();
????????????this.applicationListeners.addAll(this.earlyApplicationListeners);
????????}
????????//創(chuàng)建存儲(chǔ)早期applicationEvents容器,存儲(chǔ)早期Spring?Application事件,用于后面applicationEventMulticaster發(fā)布事件用
????????this.earlyApplicationEvents?=?new?LinkedHashSet<>();
????}
BeanFactory創(chuàng)建階段
在AbstractRefreshableApplicationContext的refreshBeanFactory實(shí)現(xiàn)里,會(huì)對(duì)這個(gè)應(yīng)用上下文的底層BeanFactory做一個(gè)刷新,如果之前有BeanFactory,會(huì)先停止,再初始化一個(gè)新的BeanFactory

protected?final?void?refreshBeanFactory()?throws?BeansException?{?????//如果有BeanFactory,先關(guān)掉這個(gè)BeanFactory??
????????if?(hasBeanFactory())?{
????????????destroyBeans();
????????????closeBeanFactory();
????????}
????????try?{????????//創(chuàng)建新的BeanFactory
????????????DefaultListableBeanFactory?beanFactory?=?createBeanFactory();????????//設(shè)置BeanFactory的id
????????????beanFactory.setSerializationId(getId());????????//設(shè)置是否允許BeanDefinition覆蓋、是否允許循環(huán)依賴
????????????customizeBeanFactory(beanFactory);????????//加載BeanDefinition
????????????loadBeanDefinitions(beanFactory);????????//設(shè)置新的BeanFactory為當(dāng)前應(yīng)用上下文IoC容器
????????????synchronized?(this.beanFactoryMonitor)?{
????????????????this.beanFactory?=?beanFactory;
????????????}
????????}
????????catch?(IOException?ex)?{
????????????throw?new?ApplicationContextException("I/O?error?parsing?bean?definition?source?for?"?+?getDisplayName(),?ex);
????????}
????}
BeanFactory準(zhǔn)備階段
配置容器上下文特征,例如上下文的ClassLoader和后置處理器。

protected?void?prepareBeanFactory(ConfigurableListableBeanFactory?beanFactory)?{
????????//設(shè)置容器使用的類加載器:?ClassLoader,默認(rèn)是線程上下文類設(shè)置的加載器
????????beanFactory.setBeanClassLoader(getClassLoader());?????//設(shè)置Bean表達(dá)式處理器,指定bean?definition中的表達(dá)是值的解析策略
????????beanFactory.setBeanExpressionResolver(new?StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));?????//添加PropertyEditorRegistrar實(shí)現(xiàn),存儲(chǔ)ResourceLoader和PropertyResolver
????????beanFactory.addPropertyEditorRegistrar(new?ResourceEditorRegistrar(this,?getEnvironment()));
????????//添加BeanPostProcessor實(shí)現(xiàn),用于處理ApplicationContext的Aware回調(diào)
????????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);
????????//注冊(cè)ResolvableDependency,這部分可以被依賴注入但不能被依賴查找
????????beanFactory.registerResolvableDependency(BeanFactory.class,?beanFactory);
????????beanFactory.registerResolvableDependency(ResourceLoader.class,?this);
????????beanFactory.registerResolvableDependency(ApplicationEventPublisher.class,?this);
????????beanFactory.registerResolvableDependency(ApplicationContext.class,?this);
????????//注冊(cè)ApplicationListener探測(cè)器,如果一個(gè)Bean實(shí)現(xiàn)了ApplicationListener接口會(huì)被當(dāng)作ApplicationListener注冊(cè)到Publisher
????????beanFactory.addBeanPostProcessor(new?ApplicationListenerDetector(this));
????????//注冊(cè)動(dòng)態(tài)織入后置處理器
????????if?(beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME))?{
????????????beanFactory.addBeanPostProcessor(new?LoadTimeWeaverAwareProcessor(beanFactory));
????????????//?Set?a?temporary?ClassLoader?for?type?matching.
????????????beanFactory.setTempClassLoader(new?ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
????????}
????????//注冊(cè)環(huán)境Bean單例對(duì)象
????????if?(!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME))?{
????????????beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME,?getEnvironment());
????????}
????????if?(!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME))?{
????????????beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME,?getEnvironment().getSystemProperties());
????????}
????????if?(!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME))?{
????????????beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME,?getEnvironment().getSystemEnvironment());
????????}
????}
BeanFactory后置處理階段
postProcessBeanFactory和invokeBeanFactoryPostProcessors都是Spring提供的擴(kuò)展方式。
postProcessBeanFactory在AbstractApplicationContext里沒(méi)有實(shí)際實(shí)現(xiàn),postProcessBeanFactory注釋如下:

?可以看出這時(shí)Spring應(yīng)用上下文內(nèi)部BeanFactory已經(jīng)標(biāo)準(zhǔn)初始化完成,這時(shí)所有Bean的BeanDefinition已經(jīng)被加載進(jìn)來(lái),但是還沒(méi)有被實(shí)例化,這時(shí)允許繼承類注冊(cè)特殊的BeanPostProcessors等內(nèi)容。
invokeBeanFactoryPostProcessors方法注釋如下:

?這個(gè)方法會(huì)實(shí)例化并且執(zhí)行所有被注冊(cè)的BeanFactoryPostProcessor的Bean,如果給定顯示順序,按顯示順序執(zhí)行,invokeBeanFactoryPostProcessors代碼如下:
protected?void?invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory?beanFactory)?{?????//處理BeanFactoryPostProcessors,這里細(xì)節(jié)挺多的,要按一定順序執(zhí)行BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry和BeanFactoryPostProcessor#postProcessBeanFactory
????????PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory,?getBeanFactoryPostProcessors());
????????//添加LoadTimeWeaverAwareProcessor
????????if?(beanFactory.getTempClassLoader()?==?null?&&?beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME))?{
????????????beanFactory.addBeanPostProcessor(new?LoadTimeWeaverAwareProcessor(beanFactory));
????????????beanFactory.setTempClassLoader(new?ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
????????}
????}
BeanFactory注冊(cè)BeanPostProcessor
registerBeanPostProcessors方法注釋如下:

?這個(gè)方法的作用就是實(shí)例化并且注冊(cè)所有BeanPostProcessor的Bean,會(huì)按給定順序注冊(cè)。
這里注冊(cè)的順序是:
先注冊(cè)實(shí)現(xiàn)PriorityOrdered的BeanPostProcessor的Bean
再注冊(cè)實(shí)現(xiàn)Ordered的BeanPostProcessor的Bean
然后注冊(cè)普通的BeanPostProcessor的Bean
后面注冊(cè)MergedBeanDefinitionPostProcess的Bean
最后注冊(cè)ApplicationListenerDetector的Bean
?初始化內(nèi)建Bean
初始化內(nèi)建Bean會(huì)初始化兩個(gè)Bean: MessageSource和ApplicationEventMulticaster。
這兩個(gè)實(shí)現(xiàn)比較類似,都是判斷當(dāng)前BeanFactory(不判斷父BeanFactory)是否包含對(duì)應(yīng)Bean,如果不包含,就創(chuàng)建并且用registerSingleton方法注冊(cè)到BeanFactory。
Spring應(yīng)用上下文刷新階段
onRefresh方法注釋如下所示:

? onRefresh方法是個(gè)可以被子類覆蓋的模板方法,可以在實(shí)例化單例前初始化特殊的Bean。
Spring事件監(jiān)聽器注冊(cè)階段
registerListeners方法注釋如下所示:

? registerListeners方法會(huì)把實(shí)現(xiàn)ApplicationListener的Bean和非Bean對(duì)象注冊(cè)到ApplicationEventMulticaster。
registerListeners方法代碼如下:
protected?void?registerListeners()?{
????????//注冊(cè)非Bean的ApplicationListener實(shí)現(xiàn)類的對(duì)象
????????for?(ApplicationListener>?listener?:?getApplicationListeners())?{
????????????getApplicationEventMulticaster().addApplicationListener(listener);
????????}
????????//注冊(cè)ApplicationListener實(shí)現(xiàn)類對(duì)應(yīng)的Bean
????????String[]?listenerBeanNames?=?getBeanNamesForType(ApplicationListener.class,?true,?false);
????????for?(String?listenerBeanName?:?listenerBeanNames)?{
????????????getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
????????}
????????//發(fā)送早期ApplicationEvent事件
????????Set?earlyEventsToProcess?=?this.earlyApplicationEvents;
????????this.earlyApplicationEvents?=?null;
????????if?(earlyEventsToProcess?!=?null)?{
????????????for?(ApplicationEvent?earlyEvent?:?earlyEventsToProcess)?{
????????????????getApplicationEventMulticaster().multicastEvent(earlyEvent);
????????????}
????????}
????}
BeanFactory初始化完成階段
finishBeanFactoryInitialization方法注釋如下所示:

?這個(gè)方法會(huì)結(jié)束Spring應(yīng)用上下文的BeanFactory的初始化,初始化所有剩余的單例Bean。
finishBeanFactoryInitialization方法代碼如下所示:
protected?void?finishBeanFactoryInitialization(ConfigurableListableBeanFactory?beanFactory)?{
????????//如果BeanFactory有ConversionService對(duì)象,關(guān)聯(lián)到BeanFactory
????????if?(beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME)?&&
????????????????beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME,?ConversionService.class))?{
????????????beanFactory.setConversionService(
????????????????????beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME,?ConversionService.class));
????????}
????????//添加StringValueResolver對(duì)象
????????if?(!beanFactory.hasEmbeddedValueResolver())?{
????????????beanFactory.addEmbeddedValueResolver(strVal?->?getEnvironment().resolvePlaceholders(strVal));
????????}
????????//依賴查找LoadTimeWeaverAware的Bean
????????String[]?weaverAwareNames?=?beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class,?false,?false);
????????for?(String?weaverAwareName?:?weaverAwareNames)?{
????????????getBean(weaverAwareName);
????????}
????????//BeanFactory臨時(shí)ClassLoader置為null
????????beanFactory.setTempClassLoader(null);
????????//BeanFactory凍結(jié)配置
????????beanFactory.freezeConfiguration();
????????//實(shí)例化所有不是懶加載的單例對(duì)象
????????beanFactory.preInstantiateSingletons();
????}
Spring應(yīng)用上下文刷新完成階段
finishRefresh方法注釋如下所示:

? finishRefresh方法結(jié)束Spring應(yīng)用上下文刷新,調(diào)用LifecycleProcessor#onRefresh方法并且發(fā)送ContextRefreshedEvent。
finishRefresh方法代碼如下所示:
protected?void?finishRefresh()?{
????????//清除ResourceLoader緩存
????????clearResourceCaches();
????????//初始化LifecycleProcessor對(duì)象
????????initLifecycleProcessor();
????????//調(diào)用LifecycleProcessor#onRefresh方法
????????getLifecycleProcessor().onRefresh();
????????//發(fā)布Spring應(yīng)用上下文已刷新事件
????????publishEvent(new?ContextRefreshedEvent(this));
????????//向MBeanServer托管Live?Bean
????????LiveBeansView.registerApplicationContext(this);
????}
start-啟動(dòng)應(yīng)用上下文
start方法代碼如下所示:
public?void?start()?{?????//啟動(dòng)LifecycleProcessor
????????getLifecycleProcessor().start();?????//發(fā)布應(yīng)用上下文啟動(dòng)事件
????????publishEvent(new?ContextStartedEvent(this));
????}
stop-停止應(yīng)用上下文
stop方法代碼如下所示:
public?void?stop()?{?????//停止LifecycleProcessor
????????getLifecycleProcessor().stop();?????//發(fā)布應(yīng)用上下文停止事件
????????publishEvent(new?ContextStoppedEvent(this));
????}
close-關(guān)閉應(yīng)用上下文
protected?void?doClose()?{
????????//檢查激活標(biāo)
????????if?(this.active.get()?&&?this.closed.compareAndSet(false,?true))?{
????????????if?(logger.isDebugEnabled())?{
????????????????logger.debug("Closing?"?+?this);
????????????}
????????//Live?Bean注銷托管
????????????LiveBeansView.unregisterApplicationContext(this);
????????????try?{
????????????????//發(fā)布Spring應(yīng)用上下文已關(guān)閉事件
????????????????publishEvent(new?ContextClosedEvent(this));
????????????}
????????????catch?(Throwable?ex)?{
????????????????logger.warn("Exception?thrown?from?ApplicationListener?handling?ContextClosedEvent",?ex);
????????????}
????????????//關(guān)閉LifecycleProcessor
????????????if?(this.lifecycleProcessor?!=?null)?{
????????????????try?{
????????????????????this.lifecycleProcessor.onClose();
????????????????}
????????????????catch?(Throwable?ex)?{
????????????????????logger.warn("Exception?thrown?from?LifecycleProcessor?on?context?close",?ex);
????????????????}
????????????}
????????????//銷毀Spring?Bean
????????????destroyBeans();
????????????//關(guān)閉BeanFactory
????????????closeBeanFactory();
????????????//回調(diào)onClose
????????????onClose();
????????????//重置本地監(jiān)聽者
????????????if?(this.earlyApplicationListeners?!=?null)?{
????????????????this.applicationListeners.clear();
????????????????this.applicationListeners.addAll(this.earlyApplicationListeners);
????????????}
????????????//激活標(biāo)設(shè)置為沒(méi)激活
????????????this.active.set(false);
????????}
????}
粉絲福利:Java從入門到入土學(xué)習(xí)路線圖
??????

??長(zhǎng)按上方微信二維碼?2 秒
感謝點(diǎn)贊支持下哈?
