1. 程式人生 > >ApplicationContext拓展功能

ApplicationContext拓展功能

一、屬性設定

對於ApplicationContext,其例項化前必須要設定的就是配置檔案的路徑--configLocation。例如:

對於非Web環境下的ClasspathXmlApplicationContext,需要通過建構函式或呼叫setConfigLocation設定配置檔案路徑;

對於Web環境下的XmlWebApplicationContext,會使用web.xml中配置的contextConfigLocation作為配置檔案路徑

//另外Web環境下使用的WebXmlApplicationContext還會儲存ServletContext物件以及一些Web環境下的引數。

二、重新整理上下文

refresh方法基本算是ApplicationContext最重要的方法之一,基本包含了ApplicationContext的大部分功能。需要注意的是,refresh方法並不是在ApplicationContext介面中定義的,而是在其子介面ConfigurableApplicationContext中定義的。下面是refresh的實現(程式碼位於AbstractApplicationContext):

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// 準備重新整理的上下文
			prepareRefresh();

			// 初始化BeanFactory,並讀取配置檔案
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// 對BeanFactory進行填充
			prepareBeanFactory(beanFactory);

			try {
				// 模版方法,由子類對初始化好的BeanFactory進行額外的處理
				postProcessBeanFactory(beanFactory);

				// 呼叫BeanFactoryPostProcessor後處理器
				invokeBeanFactoryPostProcessors(beanFactory);

				// 註冊Bean處理器
				registerBeanPostProcessors(beanFactory);

				// 初始化Message源,與國際化處理相關
				initMessageSource();

				// 初始化應用訊息廣播器,並作為一個Bean註冊到BeanFactory中
				initApplicationEventMulticaster();

				// 模版方法,交由子類實現,重新整理前的特殊處理
				onRefresh();

				// 在註冊的bean列表中查詢Listener型別的bean,註冊到訊息廣播器中
				registerListeners();

				// 提前初始化單例bean(非惰性的)
				finishBeanFactoryInitialization(beanFactory);

				// 通知生命週期處理器LifecycleProcessor重新整理過程,並且發出ContextRefreshEvent事件
				finishRefresh();
			}

			catch (BeansException ex) {
				//log..
				// 銷燬已經建立好的bean
				destroyBeans();
				// Reset 'active' flag.
				cancelRefresh(ex);
				throw ex;
			}
			finally {
				resetCommonCaches();
			}
		}
	}

重新整理的流程為:

  1. 初始化的準備工作,如系統屬性或環境變數的準備和驗證
  2. 建立BeanFactory,並讀取xml配置檔案
  3. 對BeanFactory進行功能填充
  4. 通過模版方法模式,交由子類覆蓋方法postProcessBeanFactory,對BeanFactory做額外處理
  5. 啟用BeanFactory後處理器
  6. 註冊攔截Bean建立的Bean處理器
  7. 初始化Message源
  8. 初始化訊息廣播器
  9. 留給子類初始化其他bean
  10. 將註冊的Listener bean註冊到訊息廣播器中
  11. 提前初始化單例bean(非惰性)
  12. 完成重新整理,發出ContextRefreshEvent事件,並通知生命週期處理器LifecycleProcessor重新整理過程

1、環境準備

主要是做些準備工作,對屬性進行初始化和驗證工作

	protected void prepareRefresh() {
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		this.active.set(true);
		
		//log...
		// 交由子類覆蓋
		initPropertySources();

		// 驗證需要的屬性是否都已經被放入環境中
		getEnvironment().validateRequiredProperties();

		// Allow for the collection of early ApplicationEvents,
		// to be published once the multicaster is available...
		this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
	}

2、載入BeanFactory

ApplicationContext通過obtainFreshBeanFactory函式建立BeanFactory,自此方法後也就擁有了BeanFactory的所有功能:

	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		//委託給了refreshBeanFactory方法
		refreshBeanFactory();
		//因為建立BeanFactory實在子類中實現的,所以需要通過getBeanFactory才能獲取到例項
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (logger.isDebugEnabled()) {
			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
		}
		return beanFactory;
	}

下面是refreshBeanFactory的實現(位於AbstractRefreshableApplicationContext):

	protected final void refreshBeanFactory() throws BeansException {
		//如果已經建立過BeanFactory,則銷燬所有已經建立的Bean並且重新建立BeanFactory
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			//例項化
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			beanFactory.setSerializationId(getId());
			//設定一些屬性
			customizeBeanFactory(beanFactory);
			//載入xml配置檔案
			loadBeanDefinitions(beanFactory);
			//將BeanFactory例項設定到ApplicationContext中
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

初始化流程:

  1. 如果已經建立過,則銷燬、清理掉以前建立的BeanFactory
  2. 例項化BeanFactory
  3. 定製BeanFactory
  4. 載入xml配置檔案

a、例項化BeanFactory

例項化的程式碼比較簡單,直接新建了一個DefaultListableBeanFactory,並且傳入父ApplicationContext(如果存在的話)中的BeanFactory作為父BeanFactory,下面是例項化程式碼:

	protected DefaultListableBeanFactory createBeanFactory() {
		//如果存在父ApplicationContext,會通過它獲取父BeanFactory傳出建構函式
		return new DefaultListableBeanFactory(getInternalParentBeanFactory());
	}

getInternalParentBeanFactory實現:

	protected BeanFactory getInternalParentBeanFactory() {
		return (getParent() instanceof ConfigurableApplicationContext) ?
				((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent();
	}

如果父ApplicationContext型別是ConfigurableApplicationContext,則獲取其中的BeanFactory,否則將父ApplicationContext作為BeanFactory傳入。

b、定製BeanFactory

	protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
		//allowBeanDefinitionOverriding:是否允許覆蓋同名稱的不同定義的物件
		if (this.allowBeanDefinitionOverriding != null) {
			beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
		}
		//allowCircularReferences:是否允許迴圈依賴
		if (this.allowCircularReferences != null) {
			beanFactory.setAllowCircularReferences(this.allowCircularReferences);
		}
	}

主要是對allowBeanDefinitionOverriding和allowCircularReferences屬性進行設定,在AbstractRefreshableApplicationContext中並未對這兩個屬性進行設定,而是需要由子類來進行配置。

c、載入配置檔案

	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// 為指定的BeanFactory建立XmlBeanDefinitionReader
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

		// 對XmlBeanDefinitionReader設定環境變數
		beanDefinitionReader.setEnvironment(getEnvironment());
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

		// 設定XmlBeanDefinitionReader的屬性
		initBeanDefinitionReader(beanDefinitionReader);
		//載入配置檔案
		loadBeanDefinitions(beanDefinitionReader);
	}

2、BeanFactory功能填充

對BeanFactory的功能填充是在prepareBeanFactory方法中完成的,再次之前,BeanFactory已經建立好並且完成了對xml配置檔案的解析:

	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// 設定BeanFactory的ClassLoader為當前Context的ClassLoader
		beanFactory.setBeanClassLoader(getClassLoader());
		//設定BeanFactory的表示式語言處理器,例如對#{bean.xx}呼叫相關值
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		//對bean屬性等設定管理的工具
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// 新增PostPrecessor
		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);

		// 設定自動裝配的特殊規則
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// 新增PostPrecessor(該PostProcessor功能是對AspectJ的支援)
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		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()));
		}

		// 在BeanFactory中註冊系統環境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());
		}
	}

上面程式碼中的拓展包括:

  1. 對SpEL(Spring Expression Language)的支援
  2. 對屬性編輯器的支援
  3. 增加一些內建類,如EnvironmentAware、MessageSourceAware的資訊注入
  4. 設定依賴功能需要忽略的介面
  5. 增加AspectJ的支援
  6. 將環境變數和屬性註冊的物件註冊到BeanFactory中
  7. 註冊了一些固定的依賴屬性,如BeanFactory、ApplicationContext等

3、啟用BeanFactory後處理器

BeanFactoryPostProcessor介面與BeanPostProcessor類似,能夠在Bean建立過程中修改bean的定義資訊。Spring允許BeanFactoryPostProcessor在容器例項化bean前讀取bean定義,並可以修改它。下面是啟用的程式碼:

	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		//啟用BeanFactoryPostProcessor的功能委託給了PostProcessorRegistrationDelegate
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

		//tempClassLoader為null && BeanFactory包含"loadTimeWeaver"名的bean
		//將loadTimeWeaver封裝到一個BeanPostProcessor中
		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}

PostProcessorRegistrationDelegate中的實現:

	public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		// 存放處理過的BeanFactoryPostProcessor,避免重複新增、處理
		Set<String> processedBeans = new HashSet<String>();

		//BeanDefinitionRegistry的處理
		//因為DefaultListableBeanFactory實現了BeanDefinitionRegistry介面,所以會進入下面的程式碼
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
			List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
					new LinkedList<BeanDefinitionRegistryPostProcessor>();
			/*
			*硬編碼註冊的後處理器
			*/
			//呼叫BeanDefinitionRegistryPostProcessor的額外方法
			//將處理器分類儲存到registryPostProcessors和regularPostProcessors
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				//BeanDefinitionRegistryPostProcessor繼承自BeanFactoryPostProcesso,
				//並在BeanFactoryPostProcessor基礎上還定義了postProcessBeanDefinitionRegistry方法
				//所以需要西先呼叫額外定義的方法
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryPostProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
					registryPostProcessors.add(registryPostProcessor);
				}
				else {
					//記錄常規beanFactoryPostProcessors
					regularPostProcessors.add(postProcessor);
				}
			}

			/*
			*通過配置註冊的BeanDefinitionRegistryPostProcessor後處理器
			*/
			//先獲取的是後處理器的beanName列表,而不是後處理器的例項
			//Sping會依次處理實現了PriorityOrdered、Ordered介面的後處理器,最後處理剩下的常規後處理器
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

			// 處理實現了PriorityOrdered介面的後處理器,結果暫存到priorityOrderedPostProcessors
			List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			//排序(通過PriorityOrdered介面)
			sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
			//將結果新增到registryPostProcessors
			registryPostProcessors.addAll(priorityOrderedPostProcessors);
			//和上面一樣,呼叫BeanDefinitionRegistryPostProcessor中自己定義的方法postProcessBeanDefinitionRegistry
			invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);

			//處理實現了Ordered介面的後處理器,結果暫存到orderedPostProcessors(處理過程和PriorityOrdered介面的類似)
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
			for (String ppName : postProcessorNames) {
				//該PostProcessor還未被處理過 && 實現了Ordered介面
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(beanFactory, orderedPostProcessors);	//排序(通過Ordered介面)
			//結果新增到registryPostProcessors
			registryPostProcessors.addAll(orderedPostProcessors);
			//和上面一樣,呼叫BeanDefinitionRegistryPostProcessor中自己定義的方法postProcessBeanDefinitionRegistry
			invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);

			// 最後,處理剩下的BeanDefinitionRegistryPostProcessor
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				//獲取所有BeanDefinitionRegistryPostProcessor型別的bean
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					//如果還未被處理過
					if (!processedBeans.contains(ppName)) {
						BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
						//將結果新增到registryPostProcessors
						registryPostProcessors.add(pp);
						processedBeans.add(ppName);
						//呼叫BeanDefinitionRegistryPostProcessor中自己定義的方法postProcessBeanDefinitionRegistry
						pp.postProcessBeanDefinitionRegistry(registry);
						reiterate = true;
					}
				}
			}

			// 呼叫BeanFactoryPostProcessor中定義的postProcessBeanFactory方法
			//(前面呼叫的都是registryPostProcessors,定義在BeanDefinitionRegistryPostProcessor中)
			invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			// 呼叫BeanFactoryPostProcessor中定義的postProcessBeanFactory方法.
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}
		/*
		*上面程式碼已經將硬編碼的BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor和配置中的BeanDefinitionRegistryPostProcessor分類處理了
		*後面程式碼需要處理配置中的BeanFactoryPostProcessor型別的後處理器
		*/
		// 獲取通過配置註冊的BeanFactoryPostProcessor後處理器的beanName列表
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
				
		//Spring還是會將處理器分為排序和不需要排序兩類,分別處理
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
		List<String> orderedPostProcessorNames = new ArrayList<String>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
		for (String ppName : postProcessorNames) {
			//過濾掉處理過的,剩下的就是配置中的BeanFactoryPostProcessor
			if (processedBeans.contains(ppName)) {
				// skip - already processed in first phase above
			}
			//分類新增到不同列表
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// 對實現了PriorityOrdered的處理器排序,並依次應用BeanFactoryPostProcessor
		sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// 對實現了Ordered的處理器排序,並依次應用BeanFactoryPostProcessor
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(beanFactory, orderedPostProcessors);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// 應用常規BeanFactoryPostProcessor
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		// 因為可能修改了Bean的定義資訊。所以需要清除快取的merged beanDefinitions
		beanFactory.clearMetadataCache();
	}
	
	

Spring中少有的長程式碼。。

上面程式碼功能就是應用BeanFactoryPostProcessor後處理器。但是,由一點比較特特殊的是BeanDefinitionRegistryPostProcessor繼承自BeanFactoryPostProcessor,並且還定義了一個postProcessBeanDefinitionRegistry方法(BeanFactoryPostProcessor中只定義了一個方法-postProcessBeanFactory)。所以,在應用BeanFactoryPostProcessor後處理器中的postProcessBeanFactory方法前,需要先呼叫BeanDefinitionRegistryPostProcessor中的方法。

另外,向ApplicationContext中新增BeanFactoryPostProcessor的方法由兩種:一是通過context直接呼叫addBeanFactoryPostProcessor硬編碼新增;二是通過配置檔案或@Component等註解向BeanFactory中註冊一個BeanFactoryPostProcessor型別的bean。Spring針對兩種配置,需要分類處理。

如果後處理器繼承了PriorityOrdered或Ordered介面,Spring會優先將這些處理器排序後依次呼叫。(對於硬編碼新增和配置新增的都會進行排序,但是對於Spring3以前的版本,並不會對硬編碼方式新增的後處理器進行排序)

呼叫順勳:PriorityOrdered --> Ordered --> 常規處理器

處理流程如下:

  1. BeanDefinitionRegistryPostProcessor的特殊處理,呼叫其postProcessBeanDefinitionRegistry方法
  2. 處理硬編碼的所有BeanFactoryPostProcessor後處理器以及通過配置註冊的BeanDefinitionRegistryPostProcessor後處理器:按照 PriorityOrdered --> Ordered --> 常規處理器 的順序應用BeanFactoryPostProcessor中的方法
  3. 處理剩下的通過配置註冊的BeanFactoryPostProcessor。因為BeanDefinitionRegistryPostProcessor已經在上一步中處理過了,這一步只需要按照 PriorityOrdered --> Ordered --> 常規處理器 的順序應用剩下的BeanFactoryPostProcessor

3、註冊BeanPostProcessor

Spring的大部分功能都是通過BeanPostProcessor來拓展新增的,在這一步,Spring會將BeanFactory中所有的BeanPostProcessor型別的bean註冊為後處理器,具體程式碼如下:

	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		//真正註冊的功能委託給了PostProcessorRegistrationDelegate
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}

PostProcessorRegistrationDelegate中的實現:

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

		// Register BeanPostProcessorChecker that logs an info message when
		// a bean is created during BeanPostProcessor instantiation, i.e. when
		// a bean is not eligible for getting processed by all BeanPostProcessors.
		//註冊一個特殊的BeanPostProcessor:BeanPostProcessorChecker
		//該後處理器的功能就是如果一個bean在BeanPostProcessor還沒全部載入完成的時候建立,Spring會列印一條info級別的資訊,
		//列印資訊表明該bean並沒有被所有BeanPostProcessor處理
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// 根據是否支援排序分類處理BeanPostProcessor
		// 處理順序為PriorityOrdered -> Ordered -> 常規後處理器
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
		//內部使用的BeanPostProcessor(如果後處理器型別是MergedBeanDefinitionPostProcessor的話,會放入該列表)
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
		List<String> orderedPostProcessorNames = new ArrayList<String>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
		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);
			}
		}

		// 註冊繼承自PriorityOrdered介面的BeanPostProcessor
		sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// 註冊繼承自Ordered介面的BeanPostProcessor
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(beanFactory, orderedPostProcessors);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// 註冊剩下的常規BeanPostProcessor
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		//最後重新註冊一遍內部BeanPostProcessor(會將這些BeanPostProcessor放在列表最後)
		sortPostProcessors(beanFactory, internalPostProcessors);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		// 會註冊一個特殊的BeanPostProcessor
		// ApplicationListenerDetector的功能是將型別是 ApplicationListener 的bean新增到事件廣播器
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}

上述程式碼處理流程為:

  1. 註冊BeanPostProcessorChecker。該BeanPostProcessor功能是:如果一個bean在BeanPostProcessor還沒全部載入完成的時候建立,Spring會列印一條info級別的資訊,該資訊內容表明該建立的bean並未被所有BeanPostProcessor處理
  2. 查找出BeanFactory中所有BeanPostProcessor的bean,並作為BeanPostProcessor註冊到BeanFactory中。同時支援排序介面,註冊順序為:PriorityOrdered -> Ordered -> 常規後處理器。比較特殊的是,MergedBeanDefinitionPostProcessor型別的後處理器是作為Spring內部使用的,所以會在新增到BeanPostProcessor列表末尾
  3. 註冊ApplicationListenerDetector。該BeanPostProcessor功能:在建立bean的時候,如果bean型別是ApplicationListener ,會被新增到事件廣播器

4、初始化訊息資源

	protected void initMessageSource() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		//如果配置了messageSource,就將其例項儲存到this.messageSource中
		if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
			this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
			// Make MessageSource aware of parent MessageSource.
			if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
				HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
				if (hms.getParentMessageSource() == null) {
					// Only set parent context as parent MessageSource if no parent MessageSource registered already.
					hms.setParentMessageSource(getInternalParentMessageSource());
				}
			}
			//log...
		}
		else {
			// 如果使用者沒有定義,使用預設的DelegatingMessageSource作為messageSource
			DelegatingMessageSource dms = new DelegatingMessageSource();
			dms.setParentMessageSource(getInternalParentMessageSource());
			this.messageSource = dms;
			beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
			if (logger.isDebugEnabled()) {
				logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
						"': using default [" + this.messageSource + "]");
			}
		}
	}

5、初始化ApplicationEventMulticaster

事件廣播器作用就是釋出各種事件,然後由ApplicationListener處理(前面註冊BeanPostProcessor中專門有一個ApplicationListenerDetector來註冊使用者配置的ApplicationListener),初始化並註冊的程式碼如下:

	protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		//如果BeanFactory中包含名稱為“applicationEventMulticaster”的bean,就使用該bean作為事件廣播器
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
			// log...
		}
		else {
			//使用預設的SimpleApplicationEventMulticaster作為廣播器,並註冊到BeanFactory中
			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
			//log...
		}
	}

6、註冊監聽器

在上一步初始化好事件廣播器後,Spring接著會向其新增監聽器:

	protected void registerListeners() {
		// 將前面硬編碼方式註冊的監聽器新增到廣播器中
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

		//配置檔案或者註解註冊的監聽器處理
		//為了使監聽器得到後處理器的加工,這裡並沒有例項化監聽器,而是儲存beanName
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

		// 釋出earlyApplicationEvents的事件
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (earlyEventsToProcess != null) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}

7、初始化非延遲單例

除了初始化單例bean以外,這一步還會完成一部分初始化BeanFactory的功能,包括:ConversionService的設定、凍結配置、設定EmbeddedValueResolver、初始化LoadTimeWeaverAware,原始碼如下:

	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// 初始化conversionService,如果存在的話
		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到embeddedValueResolver
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
				@Override
				public String resolveStringValue(String strVal) {
					return 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定義,表明註冊的bean定義將無法再次被修改
		beanFactory.freezeConfiguration();

		// 初始化剩餘的非延遲載入單例
		beanFactory.preInstantiateSingletons();
	}

下面是初始化非延載入單例的原始碼:

	public void preInstantiateSingletons() throws BeansException {
		//log...
		List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);

		// 遍歷beanNames,初始化其中的非惰性單例bean
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			//非Abstract || 單例 || 非惰性
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				//FactoryBean型別bean的處理
				if (isFactoryBean(beanName)) {
					//對於普通FactoryBean型別的bean,Spring會初始化其對應的FactoryBean,並不會初始化實際的bean
					final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
					boolean isEagerInit;
					//對於SmartFactoryBean型別並且isEagerInit返回true的bean,Spring會初始化真正的bean
					if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
						isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
							@Override
							public Boolean run() {
								return ((SmartFactoryBean<?>) factory).isEagerInit();
							}
						}, getAccessControlContext());
					}
					else {
						isEagerInit = (factory instanceof SmartFactoryBean &&
								((SmartFactoryBean<?>) factory).isEagerInit());
					}
					if (isEagerInit) {
						getBean(beanName);
					}
				}
				else {
					//普通bean直接呼叫getBean初始化
					getBean(beanName);
				}
			}
		}
  • 對於FactoryBean,Spring會提前初始化其FactoryBean;如果型別是SmartFactoryBean並且isEagerInit 返回true(表示需要立即初始化),Spring才會初始化其真正的bean單例
  • 對於普通bean,Spring會直接呼叫getBean進行初始化

8、finnishRefresh

在完成重新整理上下文後,Spring會通知Lifecycle呼叫其start方法(銷燬時會呼叫stop方法),進行生命週期管理;並且釋出重新整理完成的事件:

	protected void finishRefresh() {
		// 初始化lifecycleProcessor
		initLifecycleProcessor();

		// 通知lifecycleProcessor
		getLifecycleProcessor().onRefresh();

		// 釋出ContextRefreshedEvent事件
		publishEvent(new ContextRefreshedEvent(this));

		// Participate in LiveBeansView MBean, if active.
		LiveBeansView.registerApplicationContext(this);
	}
	
  1. 初始化生命週期管理器lifecycleProcessor
  2. 通知Lifecycle型別的bean,呼叫其start方法(ApplicationContext銷燬時會呼叫其stop方法)
  3. 釋出ContextRefreshedEvent事件

至此,完成了上下文的重新整理。

總結

ApplicationContext繼承了BeanFactory相關的介面,所以具備BeanFactory的所有功能,在此之上,ApplicationContext拓展的功能有:

  1. 註冊StandardBeanExpressionResolver對SpEL(Spring Expression Language)的支援
  2. 註冊ResourceEditorRegistrar,對屬性編輯器的支援
  3. 啟用BeanFactoryPostProcessor功能,例項化Bean前修改BeanFactory的狀態
  4. 添加了一些內建的BeanPostProcessor,並且將使用者配置的BeanPostProcessor註冊到BeanFactory中
  5. 增加AspectJ的支援
  6. 增加了幾個Aware介面的支援,如:EnvironmentAware、ApplicationContextAware、MessageSourceAware等
  7. MessageSource訊息源的支援,用於國際化
  8. 事件廣播器、監聽器的支援
  9. Lifecycle介面的支援,用於bean的生命週期管理