Spring應用上下文生命周期
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); } }