六.Spring之BeanFactoryProcessor、BeanDefinitionRegistryPostProcessor

提前了解BeanPostProcessor  :https://blog.csdn.net/u014203449/article/details/86665963

 BeanPostProcessor:bean后置处理器,bean创建对象初始化前后进行拦截工作的

一.BeanFactoryProcessor

现在来看看BeanFactoryProcessor:beanFactory的后置处理器;在BeanFactory标准初始化之后调用,来定制和修改BeanFactory的内容;所有的bean定义已经保存加载到beanFactory,但是bean的实例还未创建

翻译一下注释:修改容器内部bean工厂在他标出初始化之后。所有bean定义将会被加载,但是还没有bean被创建。允许重写或新添加属性甚至 早一点初始化bean。

public interface BeanFactoryPostProcessor {

	/**
	 * Modify the application context's internal bean factory after its standard
	 * initialization. All bean definitions will have been loaded, but no beans
	 * will have been instantiated yet. This allows for overriding or adding
	 * properties even to eager-initializing beans.
	 * @param beanFactory the bean factory used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

 

1.演示案例

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		System.out.println("MyBeanFactoryPostProcessor...postProcessBeanFactory...");
		int count = beanFactory.getBeanDefinitionCount();
		String[] names = beanFactory.getBeanDefinitionNames();
		System.out.println("当前BeanFactory中有"+count+" 个Bean");
		System.out.println(Arrays.asList(names));
	}

}

单元测试

	@Test
	public void test01(){
		AnnotationConfigApplicationContext applicationContext  = new AnnotationConfigApplicationContext(ExtConfig.class);

		
		applicationContext.close();
	}

 

可以获取到容器中的beanDefinition

2.原理

打个断点,看看线程执行链。

从下往上看,第一个是容器的refresh方法:

invokeBeanFactoryPostProcessors:调用BeanFactoryPostProcessors

registerBeanPostProcessors在之前看BeanPostProcessor时看过,应该熟悉。

一直点击进入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法。

内容很多,但打断点的前几步看起来很熟悉,跟BeanPostProcessor一样 会按优先级划分集合再注册,这里是按优先级划分再调用方法。

再往前几步可以看到,如何寻找所有的BeanFactoryPostProcessors:

String[] postProcessorNames =
      beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

断点继续进入,就可以看到是如何调用的:

3.总结

  BeanFactoryPostProcessor原理:
  1)、ioc容器创建对象
  2)、invokeBeanFactoryPostProcessors(beanFactory);
          如何找到所有的BeanFactoryPostProcessor并执行他们的方法;
              1)、直接在BeanFactory中找到所有类型是BeanFactoryPostProcessor的组件,并执行他们的方法
              2)、在初始化创建其他组件前面执行

 

二.BeanDefinitionRegistryPostProcessor

翻译一下注释:

类注释:对BeanFactoryPostProcessor扩展,允许注册更多的bean定义在BeanFactoryPostProcessor之前,尤其是BeanDefinitionRegistryPostProcessor可能注册一些bean定义,这些bean定义是BeanFactoryPostProcessor的定义。

方法注释:在post-processing之前执行

/**
 * Extension to the standard {@link BeanFactoryPostProcessor} SPI, allowing for
 * the registration of further bean definitions <i>before</i> regular
 * BeanFactoryPostProcessor detection kicks in. In particular,
 * BeanDefinitionRegistryPostProcessor may register further bean definitions
 * which in turn define BeanFactoryPostProcessor instances.
 *
 * @author Juergen Hoeller
 * @since 3.0.1
 * @see org.springframework.context.annotation.ConfigurationClassPostProcessor
 */
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

	/**
	 * Modify the application context's internal bean definition registry after its
	 * standard initialization. All regular bean definitions will have been loaded,
	 * but no beans will have been instantiated yet. This allows for adding further
	 * bean definitions before the next post-processing phase kicks in.
	 * @param registry the bean definition registry used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}

1.演示案例

因为BeanDefinitionRegistryPostProcessor继承BeanFactoryPostProcessor,有两个方法postProcessBeanDefinitionRegistry和postProcessBeanFactory。

在postProcessBeanDefinitionRegistr中我们新增一个BeanDefition,新增BeanDefition有两个方法:

  • RootBeanDefinition beanDefinition = new RootBeanDefinition(Blue.class);
  • AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Blue.class).getBeanDefinition();

然后用registry注册进入。

在postProcessBeanFactory把beanDefinition的个数打印,运行后会发现 beanFactory中的bean定义多了一个

@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor{

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("MyBeanDefinitionRegistryPostProcessor...bean的数量:"+beanFactory.getBeanDefinitionCount());
	}

	//BeanDefinitionRegistry Bean定义信息的保存中心,以后BeanFactory就是按照BeanDefinitionRegistry里面保存的每一个bean定义信息创建bean实例;
	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("postProcessBeanDefinitionRegistry...bean的数量:"+registry.getBeanDefinitionCount());
		//RootBeanDefinition beanDefinition = new RootBeanDefinition(Blue.class);
		AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Blue.class).getBeanDefinition();
		registry.registerBeanDefinition("hello", beanDefinition);
	}

}

单元测试

	@Test
	public void test01(){
		AnnotationConfigApplicationContext applicationContext  = new AnnotationConfigApplicationContext(ExtConfig.class);

		applicationContext.close();
	}

运行结果:

2.原理

断点打在MyBeanDefinitionRegistryPostProcessor的两个方法上,看执行流程

和BeanFactoryPostProcessor的执行流程一样,refresh 的 invokeBeanFactoryPostProcessors

断点进入到PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法,这个方法BeanFactoryPostProcessor也执行过:

很明显,执行流程是

BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry

      ---->BeanDefinitionRegistryPostProcessor.postProcessBeanFactory

                ----->BeanFactoryPostProcessor.postProcessBeanFactory

调用的方法也很简单,获取所有的BeanDefinitionRegistryPostProcessor然后循环调用

3.总结

      原理:
          1)、ioc创建对象
          2)、refresh()-》invokeBeanFactoryPostProcessors(beanFactory);
          3)、从容器中获取到所有的BeanDefinitionRegistryPostProcessor组件。
              1、依次触发所有的postProcessBeanDefinitionRegistry()方法
              2、再来触发postProcessBeanFactory()方法
  
          4)、再来从容器中找到BeanFactoryPostProcessor组件;然后依次触发postProcessBeanFactory()方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值