Spring的BeanDefinitionRegistryPostProcessor接口详解

发布时间 2023-12-23 11:44:05作者: 残城碎梦

BeanDefinitionRegistryPostProcessor介绍

BeanDefinitionRegistryPostProcessor 它是Spring框架的一个扩展点,用于对Bean定义的注册过程进行干预和定制,例如添加,修改或删除Bean定义等

BeanDefinitionRegistryPostProcessor 它继承BeanFactoryPostProcessor接口,并在其基础上扩展了一个新的方法,即:postProcessBeanDefinitionRegistry()方法。

BeanFactoryPostProcessor源码:

@FunctionalInterface
public interface BeanFactoryPostProcessor {
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

BeanDefinitionRegistryPostProcessor源码:

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
    void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}

两个方法的作用:

  • postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry):在所有Bean定义加载完成之后,Bean实例化之前被调用,允许开发人员对Bean定义进行自定义修改,例如添加,修改或删除Bean定义等。
  • postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory):继承自BeanFactoryPostProcessor接口的方法,用于在BeanFactory完成实例化之后对BeanFactory进行后置处理。

那么我们通过BeanDefinitionRegistryPostProcessor接口,开发人员可以在Spring容器启动时干预Bean的注册过程,从而实现对Bean的自定义处理。

BeanDefinitionRegistryPostProcessor 在Spring框架中的内置实现类是ConfigurationClassPostProcessor。

BeanDefinitionRegistryPostProcessor的执行时机

postProcessBeanDefinitionRegistry执行时机

  • AbstractApplicationContext#refresh

  • PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors

优先执行实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor,其次就是实现了接口Ordered的,最后才是两者都没有的。

调用BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法。

postProcessBeanFactory执行时机

跟BeanDefinitionRegistryPostProcessor的调用路径一样,在调用了所有的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法后,紧接着就会处理所有的BeanFactoryPostProcessor,按优先级调用其postProcessBeanFactory接口。

源码-来自:PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors

优先执行实现了PriorityOrdered接口的BeanFactoryPostProcessor,其次就是实现了接口Ordered的,最后才是两者都没有的。

自定义实现方式

  • 在postProcessBeanDefinitionRegistry()方法被调用的时候手工在Spring中注册了Student类的BeanDefinition信息;
  • 在postProcessBeanFactory()方法被调用的时候,从Spring容器中取出Dog类的BeanDefinition信息和Student类的实例;
@Data
public class Student{
    private String name;
    private String age;
}
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        //手工定义一个beanDefinition实例
        RootBeanDefinition beanDefinition = new RootBeanDefinition();
        //给beanDefinition填充属性
        beanDefinition.setBeanClass(Student.class);
        MutablePropertyValues propertyValues = new MutablePropertyValues();
        PropertyValue propertyValue1 = new PropertyValue("name", "张三");
        PropertyValue propertyValue2 = new PropertyValue("age", "11");
        propertyValues.addPropertyValue(propertyValue1);
        propertyValues.addPropertyValue(propertyValue2);
        beanDefinition.setPropertyValues(propertyValues);
        //注册手工定义的beanDefinition
        registry.registerBeanDefinition("student", beanDefinition);
    }
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("-----------postProcessBeanFactory start------------");
        //根据类名取出手工注册的beanDefinition
        BeanDefinition beanDefinition = beanFactory.getBeanDefinition("student");
        System.out.println(beanDefinition.getBeanClassName());
        //根据类从容器中取出手工注册的beanDefinition所描述的实例bean
        Student student = beanFactory.getBean(Student.class);
        System.out.println(student.getName());
        System.out.println(student.getAge());
        System.out.println("-----------postProcessBeanFactory end------------");
    }