首页 > 其他分享 >Spring的BeanDefinitionRegistryPostProcessor接口详解

Spring的BeanDefinitionRegistryPostProcessor接口详解

时间:2023-12-23 11:44:33浏览次数:32  
标签:Spring postProcessBeanFactory 接口 Bean 详解 BeanDefinitionRegistryPostProcessor pos

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------------");
    }

 

标签:Spring,postProcessBeanFactory,接口,Bean,详解,BeanDefinitionRegistryPostProcessor,pos
From: https://www.cnblogs.com/xfeiyun/p/17899012.html

相关文章

  • Spring的Bean后置处理器之AnnotationAwareAspectJAutoProxyCreator
    本文能帮你回答以下几个问题;AnnotationAwareAspectJAutoProxyCreator后置器的作用是什么?SpringAOP自动增强bean是如何实现的。如何在spring上下文添加AnnotationAwareAspectJAutoProxyCreator?如何利用ProxyFactory硬编码实现一个bean的增强?AnnotationAwareAspectJAutoProx......
  • 软件测试/测试开发|Linux sed命令详解
    sed命令介绍sed是streameditor(流编辑器)的简写,sed可依照脚本的指令来处理、编辑文本文件。Sed主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等。sed命令语法基本语法:sed[选项]'动作'文件名常用参数-n,--quiet,--silent取消自动打印模式空间-e......
  • Spring Boot之@Autowired注解使用区别,实战演示?
    ......
  • Java Spring Boot 配置读取进阶篇-@ConfigurationProperties && @Value
    之前我们学习了在SpringBoot如何读取application.properties/application.yaml配置文件的配置信息,在上文中我们主要是简单地实践了些简单的设置,这次我们带着同样的问题,如果配置更加复杂,我们的配置读取又应该怎么处理呢。本文的学习主要基于SpringBoot自带的库来解析配置,......
  • Spring编程式事务控制
    目录Spring编程式事务控制代码实现测试Spring编程式事务控制实际中很少使用代码实现pom.xml<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance&......
  • FLV格式详解
    本文是什么FLV(FlashVideo)是由Adobe公司开发的一种非常流行的视频格式,其简单的内容格式非常适合用于流媒体。虽然现如今这种格式已经开始被弃用,但因为各种原因,一部分企业仍然继续使用这种格式来进行流媒体传输。学习FLV格式也有利于学习同样是Adobe公司开发的实时传输协议RTM......
  • Spring基于XML的事务管理器DataSourceTransactionManager
    Spring基于XML的事务管理器DataSourceTransactionManager源码代码测试pom.xml<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instan......
  • Springboot下PageHelper分页不生效问题
    今天在做一个小项目,引入PageHelper时踩了一个坑,记录一下。解决方案参考:SpringBoot+MyBatis使用pagehelper分页插件及其注意事项(含解决分页不生效问题)环境:SpringBoot3.2.0JDK17Postgresql15PageHelper1.2.12依赖<dependency><groupId>com.github.pagehelper</......
  • springboot_3.2_freemark_基础环境配置
    springboot_3.2_freemark_基础环境配置一、前言二、环境三、相关资料四、目标五、默认配置项六、构建springboot3.2项目6.1pom.xml内容:6.2启动类6.3添加ftlh模板6.4controller内容6.5bootstrap.yml配置七、总结一、前言FreeMarker是一款模板引擎:即一种基于模板和要改变的......
  • springboot1.x升级到springboot3.x中遇到的问题总结
    springboot1.x升级到springboot3.x中遇到的问题总结springboot1.x升级到springboot3.x中遇到的问题总结前言问题:无法创建DataSource的bean对象,提示url或driverclass未配置问题:引入freemark后页面总是报404问题:bootstrap.yml不生效,配置中的内容无法读取springboot1.x升级到spring......