Spring IOC (九)refresh 分析 後續 過程 分析

花了幾篇文章 探究Spring的 BeanPostProcessorBeanFactoryPostProcessor,本文則開始接受refresh 後續邏輯。

registerBeanPostProcessors

registerBeanPostProcessors 方法主要是調用所有BeanPostProcess 的自帶方法:

	public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
		// 獲取所有的 BeanPostProcessor
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// 記錄信息,即當前beanFactory有幾個beanpostProcessor,而最終要有多少個。
		// +1 的原因是加上 BeanPostProcessorChecker 類型BeanPostProcessor
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		// BeanPostProcessorChecker 主要是檢查數量
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// 將實現PriorityOrdered的接口放入priorityOrderedPostProcessors中,Ordered 放入 orderedPostProcessorNames,其他放入 nonOrderedPostProcessorNames中。
		// 另外,如果既是PriorityOrdered又是MergedBeanDefinitionPostProcessor,則放入internalPostProcessors
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// 將所有 priorityOrderedPostProcessors 注入beanFacotory.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// 將所有orderedPostProcessors 注入beanFactory,並將MergedBeanDefinitionPostProcessor 放入internalPostProcessors 中.
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// 將所有其他的 nonOrderedPostProcessors 注入beanFactory,並將MergedBeanDefinitionPostProcessor 放入internalPostProcessors 中. 
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		// 重新再將 internalPostProcessors 注入beanFactory中.
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		//  添加 ApplicationListenerDetector 到beanFactory中Re-register post-processor for detecting inner beans as ApplicationListeners,
		// moving it to the end of the processor chain (for picking up proxies etc).
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}

上面邏輯主要是區分 不同類型的 BeanPostProcessors,並按照 PriorityOrdered -> Ordered -> 其他 順序放入beanFactory中。
而最後,將 MergedBeanDefinitionPostProcessor 類型節點,重新放到後面。而將 ApplicationListenerDetector 則用於永遠放到最後一個。
ApplicationListenerDetector 主要是將 屬於 ApplicationListener 類型bean註冊進 ApplicationEventMulticaster,以便全局事件通知。

initMessageSource

初始化一個MessageSource,主要用於 國際化i18n。如果沒有在beanFactory中配置 messageSource 的bean,則會創建一個空的messageSourceDelegatingMessageSource進行處理。

initApplicationEventMulticaster

初始化 消息廣播器,如果當前beanFactory中沒有,同樣會創建一個默認的 ApplicationEventMulticasterSimpleApplicationEventMulticaster
並配置金beanFactory:

	protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
			if (logger.isTraceEnabled()) {
				logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
			}
		}
		else {
			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
						"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
			}
		}
	}

onRefresh

可以用來做一些特殊的refresh工作,例如提前初始化一些特殊的bean等。

registerListeners

將實現了 ApplicationListener 接口的bean註冊進消息廣播中ApplicationEventMulticaster,這樣一旦有消息,就可以分發到每個對應的 ApplicationListener 類型的bean中。

	protected void registerListeners() {
		// Register statically specified listeners first.
		for (ApplicationListener<?> listener : getApplicationListeners()) {
		// 通過 applicationContext.addApplicationListeners 的bean
		// 將所有的 ApplicationListener 類型bean註冊進ApplicationEventMulticaster
			getApplicationEventMulticaster().addApplicationListener(listener);
		}
		// 將所有 實現了 ApplicationListener bean放入 applicationListnerBean中。
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}
		// 由於已經註冊了ApplicationListener,所以如果有 啓動階段發送的消息,那麼此時就可以發送
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (earlyEventsToProcess != null) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}

finishBeanFactoryInitialization

在這裏面,beanFactory的初始化將進入尾聲,則裏面,Spring會對所有bean調用getBean的初始化方法。

	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// 設置特定的類型轉化bean
		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));
		}

		// 如果沒有配置值解析器,則會使用默認的值解析器。
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// 初始化 代碼織入類,即 字節碼工具類 LoadTimeWeaverAware 
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);

		// 保存所有bean實例快照
		beanFactory.freezeConfiguration();

		// 實例化所有bean,除了lazy屬性外。並調用所有 SmartInitializingSingleton 的afterSingletonsInstantiated 方法。
		beanFactory.preInstantiateSingletons();
	}

finishRefresh

做一些refresh尾聲工作,包括清楚緩存,全局發事件消息等。

	protected void finishRefresh() {
		// 清楚相關緩存
		clearResourceCaches();
		// 如果沒有 LifecycleProcessor 類型bean,則初始化一個默認的 DefaultLifecycleProcessor bean
		initLifecycleProcessor();
		// 調用 上一步LifecycleProcessor 的refresh方法。
		getLifecycleProcessor().onRefresh();
		// 全局發佈消息。
		publishEvent(new ContextRefreshedEvent(this));
		// 將當前ApplicationContext放入 LiveBeansView中。
		LiveBeansView.registerApplicationContext(this);
	}
  1. 清除相關緩存
  2. 如果沒有 LifecycleProcessor 類型bean,則初始化一個默認的 DefaultLifecycleProcessor bean
  3. 調用 上一步LifecycleProcessor 的refresh方法。
  4. 全局發佈消息。
  5. 將當前ApplicationContext放入 LiveBeansView中。
    SpringContext設計爲支持多個容器,所以在 LiveBeansView 中會有 靜態類型的ConfigurableApplicationContext 保存容器。

最後在finnaly塊中調用 resetCommonCaches 清除一些用到的緩存,釋放佔用內存。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章