Spring應用上下文生命週期

Spring應用上下文生命週期總體分紅四個階段緩存

  • ConfigurableApplicationContext#refresh,加載或者刷新持久化配置
  • ConfigurableApplicationContext#start,啓動應用上下文
  • ConfigurableApplicationContext#stop,中止應用上下文
  • ConfigurableApplicationContext#close,關閉應用上下文,釋放鎖定資源

實際上refresh執行完成後Spring應用上下文從廣義上來講已經啓動了,start回調用LifeCycleProcessors的start方法,能夠理解refresh處理Spring應用上下文啓動須要的東西,start至關因而一個擴展,close和stop是和refresh和close相似的逆向操做。app

所以Spring應用上下文生命週期重頭戲是refresh和close兩個方法對應的實現。post

refresh-刷新應用上下文

整個refresh階段代碼以下所示:ui

從代碼能夠看出,refresh總體分爲如下幾個階段:this

  • 準備刷新階段: prepareRefresh
  • BeanFactory建立階段: obtainFreshBeanFactory
  • BeanFactory準備階段: prepareBeanFactory
  • BeanFactory後置處理階段: postProcessBeanFactory、invokeBeanFactoryPostProcessors
  • BeanFactory註冊BeanPostProcessor階段: registerBeanPostProcessors
  • 初始化內建Bean: initMessageSource、initApplicationEventMulticaster
  • Spring應用上下文刷新階段: onRefresh
  • Spring事件監聽器註冊階段: registerListener
  • BeanFactory初始化完成階段: finishBeanFactoryInitialization
  • Spring應用上下文刷新完成階段: finishRefresh

準備刷新階段

prepareRefresh方法註釋以下所示,能夠看出,這個方法主要作了三件事來準備上下文刷新:spa

  • 設置啓動時間
  • 設置激活標
  • 執行任何初始化屬性來源

    protected void prepareRefresh() {
        //設置啓動時間、激活標
        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());
            }
        }

        //初始化屬性源,擴展用
        initPropertySources();

        //校驗必要屬性
        getEnvironment().validateRequiredProperties();

        //建立存儲早期applicationListeners容器
        if (this.earlyApplicationListeners == null) {
            this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
        }
        else {
            this.applicationListeners.clear();
            this.applicationListeners.addAll(this.earlyApplicationListeners);
        }

        //建立存儲早期applicationEvents容器,存儲早期Spring Application事件,用於後面applicationEventMulticaster發佈事件用
        this.earlyApplicationEvents = new LinkedHashSet<>();
    }

BeanFactory建立階段

在AbstractRefreshableApplicationContext的refreshBeanFactory實現裏,會對這個應用上下文的底層BeanFactory作一個刷新,若是以前有BeanFactory,會先中止,再初始化一個新的BeanFactory線程

    protected final void refreshBeanFactory() throws BeansException {
     //若是有BeanFactory,先關掉這個BeanFactory  
if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try {
       //建立新的BeanFactory DefaultListableBeanFactory beanFactory
= createBeanFactory();
       //設置BeanFactory的id beanFactory.setSerializationId(getId());
       //設置是否容許BeanDefinition覆蓋、是否容許循環依賴 customizeBeanFactory(beanFactory);
       //加載BeanDefinition loadBeanDefinitions(beanFactory);
       //設置新的BeanFactory爲當前應用上下文IoC容器
synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }

BeanFactory準備階段

配置容器上下文特徵,例如上下文的ClassLoader和後置處理器。debug

    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        //設置容器使用的類加載器: ClassLoader,默認是線程上下文類設置的加載器
        beanFactory.setBeanClassLoader(getClassLoader());
     //設置Bean表達式處理器,指定bean definition中的表達是值的解析策略 beanFactory.setBeanExpressionResolver(
new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
     //添加PropertyEditorRegistrar實現,存儲ResourceLoader和PropertyResolver beanFactory.addPropertyEditorRegistrar(
new ResourceEditorRegistrar(this, getEnvironment())); //添加BeanPostProcessor實現,用於處理ApplicationContext的Aware回調 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); //註冊ResolvableDependency,這部分能夠被依賴注入但不能被依賴查找 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); //註冊ApplicationListener探測器,若是一個Bean實現了ApplicationListener接口會被看成ApplicationListener註冊到Publisher beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); //註冊動態織入後置處理器 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())); } //註冊環境Bean單例對象 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提供的擴展方式。code

postProcessBeanFactory在AbstractApplicationContext裏沒有實際實現,postProcessBeanFactory註釋以下:對象

 能夠看出這時Spring應用上下文內部BeanFactory已經標準初始化完成,這時全部Bean的BeanDefinition已經被加載進來,可是尚未被實例化,這時容許繼承類註冊特殊的BeanPostProcessors等內容。

invokeBeanFactoryPostProcessors方法註釋以下:

 這個方法會實例化而且執行全部被註冊的BeanFactoryPostProcessor的Bean,若是給定顯示順序,按顯示順序執行,invokeBeanFactoryPostProcessors代碼以下:

    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
     //處理BeanFactoryPostProcessors,這裏細節挺多的,要按必定順序執行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註冊BeanPostProcessor

registerBeanPostProcessors方法註釋以下:

 這個方法的做用就是實例化而且註冊全部BeanPostProcessor的Bean,會按給定順序註冊。

這裏註冊的順序是:

  • 先註冊實現PriorityOrdered的BeanPostProcessor的Bean
  • 再註冊實現Ordered的BeanPostProcessor的Bean
  • 而後註冊普通的BeanPostProcessor的Bean
  • 後面註冊MergedBeanDefinitionPostProcess的Bean
  • 最後註冊ApplicationListenerDetector的Bean

 初始化內建Bean

初始化內建Bean會初始化兩個Bean: MessageSource和ApplicationEventMulticaster。

這兩個實現比較相似,都是判斷當前BeanFactory(不判斷父BeanFactory)是否包含對應Bean,若是不包含,就建立而且用registerSingleton方法註冊到BeanFactory。

Spring應用上下文刷新階段

onRefresh方法註釋以下所示:

  onRefresh方法是個能夠被子類覆蓋的模板方法,能夠在實例化單例前初始化特殊的Bean。

Spring事件監聽器註冊階段

registerListeners方法註釋以下所示:

  registerListeners方法會把實現ApplicationListener的Bean和非Bean對象註冊到ApplicationEventMulticaster。

registerListeners方法代碼以下:

    protected void registerListeners() {
        //註冊非Bean的ApplicationListener實現類的對象
        for (ApplicationListener<?> listener : getApplicationListeners()) {
            getApplicationEventMulticaster().addApplicationListener(listener);
        }

        //註冊ApplicationListener實現類對應的Bean
        String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
        for (String listenerBeanName : listenerBeanNames) {
            getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }

        //發送早期ApplicationEvent事件
        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (earlyEventsToProcess != null) {
            for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
                getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }
    }

BeanFactory初始化完成階段

finishBeanFactoryInitialization方法註釋以下所示:

 這個方法會結束Spring應用上下文的BeanFactory的初始化,初始化全部剩餘的單例Bean。

finishBeanFactoryInitialization方法代碼以下所示:

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        //若是BeanFactory有ConversionService對象,關聯到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對象
        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臨時ClassLoader置爲null
        beanFactory.setTempClassLoader(null);

        //BeanFactory凍結配置
        beanFactory.freezeConfiguration();

        //實例化全部不是懶加載的單例對象
        beanFactory.preInstantiateSingletons();
    }

Spring應用上下文刷新完成階段

finishRefresh方法註釋以下所示:

  finishRefresh方法結束Spring應用上下文刷新,調用LifecycleProcessor#onRefresh方法而且發送ContextRefreshedEvent。

finishRefresh方法代碼以下所示:

    protected void finishRefresh() {
        //清除ResourceLoader緩存
        clearResourceCaches();

        //初始化LifecycleProcessor對象
        initLifecycleProcessor();

        //調用LifecycleProcessor#onRefresh方法
        getLifecycleProcessor().onRefresh();

        //發佈Spring應用上下文已刷新事件
        publishEvent(new ContextRefreshedEvent(this));

        //向MBeanServer託管Live Bean
        LiveBeansView.registerApplicationContext(this);
    }

start-啓動應用上下文

start方法代碼以下所示:

    public void start() {
     //啓動LifecycleProcessor getLifecycleProcessor().start();
     //發佈應用上下文啓動事件 publishEvent(
new ContextStartedEvent(this)); }

stop-中止應用上下文

stop方法代碼以下所示:

    public void stop() {
     //中止LifecycleProcessor getLifecycleProcessor().stop();
     //發佈應用上下文中止事件 publishEvent(
new ContextStoppedEvent(this)); }

close-關閉應用上下文

    protected void doClose() {
        //檢查激活標
        if (this.active.get() && this.closed.compareAndSet(false, true)) {
            if (logger.isDebugEnabled()) {
                logger.debug("Closing " + this);
            }
        //Live Bean註銷託管
            LiveBeansView.unregisterApplicationContext(this);

            try {
                //發佈Spring應用上下文已關閉事件
                publishEvent(new ContextClosedEvent(this));
            }
            catch (Throwable ex) {
                logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
            }

            //關閉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();

            //關閉BeanFactory
            closeBeanFactory();

            //回調onClose
            onClose();

            //重置本地監聽者
            if (this.earlyApplicationListeners != null) {
                this.applicationListeners.clear();
                this.applicationListeners.addAll(this.earlyApplicationListeners);
            }

            //激活標設置爲沒激活
            this.active.set(false);
        }
    }
相關文章
相關標籤/搜索