BeanFactoryPostProcessor与BeanDefinitionRegistryPostProcessor用法与原理

BeanFactoryPostProcessor与BeanDefinitionRegistryPostProcessor用法与原理

BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor都是接口,BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口。实现类用来修改Spring容器的beanDefinition行为的,注意这里的两个不是bean的后置处理器,可以称为bean工厂的后置处理器和bean注册中心的后置处理器,针对的时beanDefinition的map,并不是单个的beanDefinition,关键的一点是,此时的这些bean还没有被实例化。具体用法参考下面例子。

用法案例

  1. 搭建一个spring环境,本案例使用5.2.10版本,配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tool"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tool http://www.springframework.org/schema/tool/spring-tool.xsd">
        
        <bean id="user" class="com.li.study.bean.User"/>
    
    </beans>
    

    创建两个测试bean,省略get,set方法,重写toString()方法

    public class User {
    
        private String name="li";
    
        public User(String name) {
            this.name = name;
        }
    
        public User() {
        }
    }
    
    public class Studant {
    
        private int id;
        private String name;
        private int age;
    
        public Studant() {
        }
    }
    

    测试主程序入口

    public class TestBean {
    
        public static void main(String[] args) {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
    
    //         AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
            final Object bean = context.getBean("user");
            System.out.println(bean);
        }
    }
    

    执行结果:User{name=‘li’}

  2. 由于BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口,这里只测试BeanDefinitionRegistryPostProcessor接口功能。创建一个实现BeanDefinitionRegistryPostProcessor接口的类MyBeanDefinitionRegistryPostProcessor

    public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
         @Override
         public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
             GenericBeanDefinition beanDefinition = (GenericBeanDefinition) registry.getBeanDefinition("user");
             System.out.println("修改user的类型");
             beanDefinition.setBeanClass(Studant.class);
         }
     
         @Override
         public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
     
             Object bean = beanFactory.getBean("user");
             System.out.println(bean+"\tbean的hash值="+bean.hashCode());
         }
     }
    

    将加入到上面的xml配置中,再次执行,查看结果:

    修改user的类型
    Studant{id=0, name='null', age=0}	bean的hash值=1223685984
    Studant{id=0, name='null', age=0}
    

    通过观察结果可以发现,bean的类型发生了改变,因为在实例化bean之前通过MyBeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry方法改变了bean的类型,在postProcessBeanFactory方法中将bean实例化。可以判断出两个方法的执行顺序。

  3. 总结

    通过两个方法的参数可以推断出两个方法的作用,BeanDefinitionRegistry只可以获取,修改beanDefinition,ConfigurableListableBeanFactory不但可以修改beanDefinition,还可以getBean(),也就是实例化某个bean,将bean的实例化过程提前,可以满足用户的某些特殊需求。除此之外,可以配置多个实现BeanDefinitionRegistryPostProcessor接口的bean,会按照被加载的顺序执行,并且可以通过配置指定执行的先后顺序。

原理分析

通过分析源代码的方式解释上述案例,以下源码分析需要spring源码基础,不可能从头开始介绍spring源码。如果不熟悉可能会引起不适,请做好准备。

首先说明,本阶段是bean加载完成后,实例化之前。
源码入口在AbstractApplicationContext类的public void refresh() 方法中的invokeBeanFactoryPostProcessors(beanFactory);往下走一步就来到这个方法,这里有全部的实现逻辑。

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

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		Set<String> processedBeans = new HashSet<>();

        //这里beanFactory的类型DefaultListableBeanFactory,通过xml配置加载容器
        //就是实例化的DefaultListableBeanFactory对象,DefaultListableBeanFactory实现了BeanDefinitionRegistry接口
		if (beanFactory instanceof BeanDefinitionRegistry)   
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

            //beanFactoryPostProcessors获取的是容器本身的beanFactory后置处理器,不包括在用户自定义的
            //这里逻辑就是将BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor分开处理
            //先执行所有postProcessBeanDefinitionRegistry方法
            //找到所有的BeanFactoryPostProcessor接口保存到regularPostProcessors起来,先不执行
			for (beanFactoryPostProcessors postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				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.
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			//找到所有实现BeanDefinitionRegistryPostProcessor的bean的name
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				    //实例化同时实现类PriorityOrdered接口的bean,保存到currentRegistryProcessors
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					//BeanFactoryPostProcessor接口的方法保存,先不执行
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);//排序
			registryProcessors.addAll(currentRegistryProcessors);
			//只执行同时实现PriorityOrdered接口的postProcessBeanDefinitionRegistry方法
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
				    //实例化同时实现Ordered接口的
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);//排序
			registryProcessors.addAll(currentRegistryProcessors);
			//只执行同时实现Ordered接口的postProcessBeanDefinitionRegistry方法
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			// 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)) {
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						processedBeans.add(ppName);
						reiterate = true;
					}
				}
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				registryProcessors.addAll(currentRegistryProcessors);
				//执行所有postProcessBeanDefinitionRegistry方法
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
				currentRegistryProcessors.clear();
			}

			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			//执行所有找到的BeanDefinitionRegistryPostProcessor接口中的postProcessBeanFactory方法
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			//执行所有找到的BeanFactoryPostProcessor接口中的postProcessBeanFactory方法
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

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

        //到此,执行了所有实现了的BeanDefinitionRegistryPostProcessor接口的postProcessBeanFactory方法,包括内置的和自定义的
        //执行了所有内置的实现类BeanFactoryPostProcessor接口中的postProcessBeanFactory方法,不包括自定义配置的
        //下面的逻辑就是,寻找,实例化自定义的BeanFactoryPostProcessor接口并执行
        
        //找到所有实现BeanFactoryPostProcessor接口的bean的name
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (processedBeans.contains(ppName)) {
				// skip - already processed in first phase above
			}
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
			    //实现PriorityOrdered接口的
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
			    //实现Ordered接口的
				orderedPostProcessorNames.add(ppName);
			}
			else {
			    //普通的
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		//执行实现PriorityOrdered接口的
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);//排序
		//执行实现Ordered接口的
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		//最后执行其他的
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		// Clear cached merged bean definitions since the post-processors might have
		// modified the original metadata, e.g. replacing placeholders in values...
		beanFactory.clearMetadataCache();
	}

整个代码虽然长,但是逻辑还是比较清晰的,总结起来就是

  • 按顺序查找,实例化,执行,内置的,实现 PriorityOrdered接口的,实现Ordered接口的和正常的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法,
  • 将所有的BeanDefinitionRegistryPostProcessor的父接口BeanFactoryPostProcessor保存起来,然后执行postProcessBeanFactory方法
  • 按顺序查找,实例化,执行内置的,实现 PriorityOrdered接口的,实现Ordered接口的和正常的BeanFactoryPostProcessor的行postProcessBeanFactory方法
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值