spring-BeanDefinitionRegistryPostProcessor、BeanFactoryPostProcessor、BeanPostProcessor三者区别

一、三者的执行顺序

BeanDefinitionRegistryPostProcessor接口

唯一方法:BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
作用:所有常规bd已经加载完毕,然后可以再添加一些额外的bd。
执行顺序:三个中最先执行的

比如下面几个都是Spring自己定义的,都是对BeanDefinitionRegistryPostProcessor接口的实现

  1. ConfigurationClassPostProcessor -----处理@Configuration注解

注意:BeanDefinitionRegistryPostProcessor接口继承了BeanFactoryPostProcessor接口。官网的建议是BeanDefinitionRegistryPostProcessor用来添加额外的bd。

BeanFactoryPostProcessor接口

唯一方法:BeanFactoryPostProcessor#postProcessBeanFactory
作用:Bean实例化之前执行,所有的bd已经全部加载完毕,然后可以对这些bd做一些属性的修改或者添加工作。
执行时间:BeanFactoryPostProcessor是在spring容器加载了bean的定义文件之后,在Bean实例化之前执行

官网的建议是BeanDefinitionRegistryPostProcessor用来添加额外的bd,而BeanFactoryPostProcessor用来修改bd
Spring允许BeanFactoryPostProcessor在容器实例化任何其它Bean之前读取配置元数据,并可以根据需要进行修改

spring中,有内置的一些BeanFactoryPostProcessor实现类,常用的有:

  1. org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
  2. org.springframework.beans.factory.config.PropertyOverrideConfigurer
  3. org.springframework.beans.factory.config.CustomEditorConfigurer:用来注册自定义的属性编辑器

BeanPostProcessor

作用:针对Bean实例化之后做一些逻辑处理
执行顺序:spring容器加载了Bean的定义并且实例化bean之后执行的。BeanPostProcessor的执行顺序是在BeanFactoryPostProcessor之后

spring中,有内置的一些BeanPostProcessor实现类,例如:

  1. org.springframework.context.annotation.CommonAnnotationBeanPostProcessor:支持@Resource注解的注入
  2. org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor:支持@Required注解的注入
  3. org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor:支持@Autowired注解的注入
  4. org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor:支持@PersistenceUnit和@PersistenceContext注解的注入
  5. org.springframework.context.support.ApplicationContextAwareProcessor:用来为bean注入ApplicationContext等容器对象

三者的执行顺序:

BeanDefinitionRegistryPostProcessor > BeanFactoryPostProcessor > BeanPostProcessor

在spring的启动过程中,在方法PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors执行的时候,从这里可以看出来Spring执行这两个扩展类的先后顺序是这样的:

1.先执行BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry方法
2.在执行BeanDefinitionRegistryPostProcessor#postProcessBeanFactory方法,因为BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor
3.在执行BeanFactoryPostProcessor#postProcessBeanFactory方法
4.最后BeanPostProcessor的回调方法

二、在实例化的时候,关于BeanPostProcessor的执行顺序

1、构造方法
2、applyBeanPostProcessorsBeforeInitialization
3、invokeInitMethods
4、applyBeanPostProcessorsAfterInitialization

代码如下:实例化bean

sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
	@Override
	public Object getObject() throws BeansException {
		try {
			return createBean(beanName, mbd, args);
		}
		catch (BeansException ex) {
			destroySingleton(beanName);
			throw ex;
		}
	}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);

上面包含2个重要的方法

1、createBean
2、getObjectForBeanInstance

createBean里面会执行doCreateBean方法

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args){
	instanceWrapper = createBeanInstance(beanName, mbd, args);//执行Bean的构造方法
	......
	populateBean(beanName, mbd, instanceWrapper); //这个方法很熟悉
	......
	if (exposedObject != null) {
		//初始化,下面会介绍initializeBean方法
		exposedObject = initializeBean(beanName, exposedObject, mbd);
	}
}

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
	//这里会执行BeanPostProcessors的before方法
	Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

	//init方法,比如实现了InitializingBean类,需要重行init方法
	invokeInitMethods(beanName, wrappedBean, mbd);

	//这里会执行BeanPostProcessors的After方法
	wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

	return wrappedBean;
}

可以看出bean的实例化都在createBean里面就完成了,而Mapper的实例化确实在getObjectForBeanInstance方法里面完成的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

信仰_273993243

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值