zoukankan      html  css  js  c++  java
  • Spring源码解析(二) -- invokeBeanFactoryPostProcessors

      上一篇分析了Spring容器启动时,beanfactory的初始化,此时在beanfactory中存在了全部的BeanDefinition,注意此时还没有任何一个bean,有的只是BeanDefinition。

      本篇我们分析Spring启动时实例化BeanFactoryPostProcessor并启动的过程。

      

      

      今天就要好好分析下2中的代码。

      一路跟踪代码来到了 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>();
    
    			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
    				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
    					BeanDefinitionRegistryPostProcessor registryPostProcessor =
    							(BeanDefinitionRegistryPostProcessor) postProcessor;
    					registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
    					registryPostProcessors.add(registryPostProcessor);
    				}
    				else {
    					regularPostProcessors.add(postProcessor);
    				}
    			}
    

      这部分不用分析,一般来说传进来的 beanFactoryPostProcessors 都是空的

    String[] postProcessorNames =
    					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    
    			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
    			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);
    				}
    			}
    			sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
    			registryPostProcessors.addAll(priorityOrderedPostProcessors);
    			invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);
    
    			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
    			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    			List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
    			for (String ppName : postProcessorNames) {
    				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
    					orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    					processedBeans.add(ppName);
    				}
    			}
    			sortPostProcessors(beanFactory, orderedPostProcessors);
    			registryPostProcessors.addAll(orderedPostProcessors);
    			invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);
    
    			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
    			boolean reiterate = true;
    			while (reiterate) {
    				reiterate = false;
    				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    				for (String ppName : postProcessorNames) {
    					if (!processedBeans.contains(ppName)) {
    						BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
    						registryPostProcessors.add(pp);
    						processedBeans.add(ppName);
    						pp.postProcessBeanDefinitionRegistry(registry);
    						reiterate = true;
    					}
    				}
    			}
    
    			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
    			invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
    			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    

      先把 BeanDefinitionRegistryPostProcessor的实现类找出来,并且要按照优先级来实例化并执行先执行 PriorityOrdered,其次  Ordered 最后是普通的BeanDefinitionRegistryPostProcessor。

      那么BeanDefinitionRegistryPostProcessor是什么呢?

    public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor
    

      它的实现类是 ConfigurationClassPostProcessor,这个类是专门处理Configuration这个标签的。也就是从spring3.0开始,spring可以使用无配置文件的启动方式了,而是使用配置类的方式。ConfigurationClassPostProcessor就是专门用来解析配置类,并且把beanDefinition进行注册的工具类。

      关于BeanDefinitionRegistryPostProcessor 的处理就结束了,接下来就是普通的 BeanFactoryPostProcessor了。

    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进行排序,优先级高的肯定先执行。同时注意,BeanFactoryPostProcessor也是要通过 beanFactory.getBean 完成实例化的。

      关于BeanFactoryPostProcessor的作用,通常都是改变BeanDefinition的定义,这样可以在bean的实例化前做一些调整。也可以把自己要加入到spring容器的beanDefinition通过beanfactoryPostProccessor加入beanDefinition。因此,BeanFactoryPostProcessor一定是先于普通的bean先实例化并执行。

  • 相关阅读:
    C#中Split用法
    ASP.NET Get和Post两种提交的区别:
    BAT常用命令
    SQL语句:在两个数据库间复制表结构和数据数据库
    C#中Array与ArrayList用法及转换
    找出输入区间内的回文质数
    (转)加藤嘉一:中国大学生,你没资格抱怨政府
    最长公共子序列(LCS)
    shell(希尔)排序
    关于Ubuntu中google chrome浏览器字体的设置
  • 原文地址:https://www.cnblogs.com/juniorMa/p/13691551.html
Copyright © 2011-2022 走看看