首頁>技術>

Spring應用上下文生命週期整體分成四個階段

ConfigurableApplicationContext#refresh,載入或者重新整理持久化配置ConfigurableApplicationContext#start,啟動應用上下文ConfigurableApplicationContext#stop,停止應用上下文ConfigurableApplicationContext#close,關閉應用上下文,釋放鎖定資源

實際上refresh執行完成後Spring應用上下文從廣義上來說已經啟動了,start回撥用LifeCycleProcessors的start方法,可以理解refresh處理Spring應用上下文啟動需要的東西,start相當於是一個擴充套件,close和stop是和refresh和close類似的逆向操作。

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

refresh-重新整理應用上下文

整個refresh階段程式碼如下所示:

從程式碼可以看出,refresh整體分為以下幾個階段:

準備重新整理階段: prepareRefreshBeanFactory建立階段: obtainFreshBeanFactoryBeanFactory準備階段: prepareBeanFactoryBeanFactory後置處理階段: postProcessBeanFactory、invokeBeanFactoryPostProcessorsBeanFactory註冊BeanPostProcessor階段: registerBeanPostProcessors初始化內建Bean: initMessageSource、initApplicationEventMulticasterSpring應用上下文重新整理階段: onRefreshSpring事件監聽器註冊階段: registerListenerBeanFactory初始化完成階段: finishBeanFactoryInitializationSpring應用上下文重新整理完成階段: finishRefresh準備重新整理階段

prepareRefresh方法註釋如下所示,可以看出,這個方法主要做了三件事來準備上下文重新整理:

設定啟動時間設定啟用標執行任何初始化屬性來源
    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和後置處理器。

    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提供的擴充套件方式。

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);        }    }

原文連結:https://www.cnblogs.com/gouden/p/14402955.html

12
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 得到 hybrid 架構的演進之路