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整體分為以下幾個階段:
- 準備重新整理階段: prepareRefresh
- BeanFactory建立階段: obtainFreshBeanFactory
- BeanFactory準備階段: prepareBeanFactory
- BeanFactory後置處理階段: postProcessBeanFactory、invokeBeanFactoryPostProcessors
- BeanFactory註冊BeanPostProcessor階段: registerBeanPostProcessors
- 初始化內建Bean: initMessageSource、initApplicationEventMulticaster
- Spring應用上下文重新整理階段: onRefresh
- Spring事件監聽器註冊階段: registerListener
- BeanFactory初始化完成階段: finishBeanFactoryInitialization
- Spring應用上下文重新整理完成階段: 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); } }