Spring源碼情操陶冶-AbstractApplicationContext#invokeBeanFactoryPostProcessors


閱讀源碼有利於陶冶情操,承接前文Spring源碼情操陶冶-AbstractApplicationContext#postProcessBeanFactory
約定:web.xml中配置的contextClassXmlWebApplicationContext

瞧瞧官方注釋

	/**
	 * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
	 * respecting explicit order if given.
	 * <p>Must be called before singleton instantiation.必須在單例實例化前調用
	 */

主要是實例化和調用所有已注冊的BeanFactoryPostProcessors beans

源碼簡析

對應的代碼清單如下

	//通過一個委托類來處理實例化調用
	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
	}

PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors

簡單的看下委托類中的此方法源碼,代碼清單如下

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

		// 第一步,Invoke BeanDefinitionRegistryPostProcessors first, if any.
		Set<String> processedBeans = new HashSet<String>();
		//條件滿足
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
			List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
					new LinkedList<BeanDefinitionRegistryPostProcessor>();
			//剛開始進來beanFactoryPostProcessors為空
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				//BeanDefinitionRegistryPostProcessor目前該接口的實現者為MapperScannerConfigurer/ConfigurationClassPostProcessor
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryPostProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					//調用postProcessBeanDefinitionRegistry接口,比如MapperScannerConfigurer則會進行掃描注冊接口bean操作
					registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
					registryPostProcessors.add(registryPostProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}

			// Do not initialize FactoryBeans here: We need to leave all regular beans
			// uninitialized to let the bean factory post-processors apply to them!
			// Separate between BeanDefinitionRegistryPostProcessors that implement
			// PriorityOrdered, Ordered, and the rest.
			//尋找實現了BeanDefinitionRegistryPostProcessor接口類的beans
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.這里只有ConfigurationClassPostProcessor類才操作
			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);
				}
			}
			***
			省略部分代碼
			***

			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			// Invoke factory processors registered with the context instance.
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}

		//第二步,處理注冊在bean工廠中BeanFactoryPostProcessor接口實現類並調用公用的方法,比如PropertyResourceConfigurer資源文件解析類
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest. 執行的優先權
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
		List<String> orderedPostProcessorNames = new ArrayList<String>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
		for (String ppName : postProcessorNames) {
			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);
			}
		}

		***
		省略部分代碼
		***
	}

主要功能是對實現BeanFactoryPostProcessor的bean類進行調用公共接口方法postProcessBeanFactory,並相關的信息可關聯至ConfigurableListableBeanFactorybeanFactory。常見的使用類為PropertyPlaceholderConfigurer文件解析類、MapperScannerConfigurer SQL接口注冊類。公共接口的調用前者會對每個bean對象含有${}進行解析替換,后者會注冊mapper class接口類並嘗試解析注解

下節預告

Spring源碼情操陶冶-AbstractApplicationContext#registerBeanPostProcessors


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM