BeanDefinitionRegistryPostProcessor使用以及源码解析

2,972 阅读2分钟

开始自己的写文章之旅

1. BeanDefinitionRegistryPostProcessor 作用

根据源码对此类的解释:对标准{@link BeanFactoryPostProcessor} SPI的扩展,允许在常规BeanFactoryPostProcessor检测开始之前注册更多的bean定义。开发者可以通过该类实现扩展,在类初始之前对beanDefinition进行修改以及新增注册。

2. 写一个类实现BeanDefinitionRegistryPostProcessor 往容器中手动注册一个BeanDefinition。

public class User {
   private String name;
   private Integer age;

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   public Integer getAge() {
      return age;
   }

   public void setAge(Integer age) {
      this.age = age;
   }
}

自定义BeanDefinitionRegistryPostProcessor

public class DbBeanFactoryProcess implements BeanDefinitionRegistryPostProcessor {

   private static final Logger logger = LoggerFactory.getLogger(DbBeanFactoryProcess.class);

   @Override
   public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
      logger.debug("postProcessBeanDefinitionRegistry count is {}",registry.getBeanDefinitionCount());
      GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
      beanDefinition.setBeanClass(User.class);
      beanDefinition.getPropertyValues().add("name","张三");
      registry.registerBeanDefinition("BEAN_DEFITION_NAME_FOR_TEST",beanDefinition);
      logger.debug("postProcessBeanDefinitionRegistry count is {}",registry.getBeanDefinitionCount());
   }

   @Override
   public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
      logger.debug("postProcessBeanFactory count is {}",beanFactory.getBeanDefinitionCount());
   }
}

测试类

@Test
public void testBeanProcess(){
   AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanProcessConfig.class);
   User user = (User)context.getBean("BEAN_DEFITION_NAME_FOR_TEST");
   logger.debug("test user name is {}",user.getName());
}

结果:

14:31:23.633 [main] DEBUG org.my.study.beanprocess.DbBeanFactoryProcess - postProcessBeanDefinitionRegistry count is 6
14:31:23.642 [main] DEBUG org.my.study.beanprocess.DbBeanFactoryProcess - postProcessBeanDefinitionRegistry count is 7
14:31:23.863 [main] DEBUG org.my.study.beanprocess.DbBeanFactoryProcess - postProcessBeanFactory count is 7
14:31:24.007 [main] DEBUG org.my.study.aop.ConfigTest - test user name is 张三

BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor接口,BeanFactoryPostProcessor 接口里postProcessBeanFactory 是在BeanDefinitionRegistryPostProcessor 类里postProcessBeanDefinitionRegistry方法之后执行。postProcessBeanDefinitionRegistry是在BeanDefinition注册时被执行,而postProcessBeanFactory 是所有的(All bean definitions will have been loaded)bean definitions都被加载之后执行,类初始化之前执行。这个也可以对类属性进行修改以及新增BeanDefinition,这个两个方法都可以实现。

3、源码解析

首先根据测试类里AnnotationConfigApplicationContext类进入refresh() 方法,然后调用invokeBeanFactoryPostProcessors(beanFactory)方法,最终进入该方法,循环时会调用自定义实现BeanDefinitionRegistryPostProcessor的类里的postProcessBeanDefinitionRegistry方法,此时会传入spring容器实现的BeanDefinitionRegistry,自定义实现的类里方法可以自定义相关的BeanDefinition,包括新增,以及修改原有的属性。

此时我们已经执行了postProcessBeanDefinitionRegistry,接着我们可以看到自定义实现类的另一个方法postProcessBeanFactory。同样进入invokeBeanFactoryPostProcessors(beanFactory)方法,继续往下走可以看到调用postProcessBeanFactory方法。

现在,调用到目前为止已处理的所有处理器的postProcessBeanFactory回调.自定义BeanDefinitionRegistryPostProcessor也执行完毕。