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的生命週期管理

 

 

 

 

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