<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Spring應(yīng)用上下文生命周期

          共 12372字,需瀏覽 25分鐘

           ·

          2021-02-19 10:07

          點(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)贊支持下哈?

          瀏覽 52
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲无码视频免费 | 日韩一级a免费在线视频 | 色香蕉网 | 色五月天激情 | 啪啪网视频 |