Spring IOC源码:registerBeanPostProcessors 详解

简介: Spring IOC源码:registerBeanPostProcessors 详解

文章目录

Spring源码系列:

Spring IOC源码:简单易懂的Spring IOC 思路介绍

Spring IOC源码:核心流程介绍

Spring IOC源码:ApplicationContext刷新前准备工作

Spring IOC源码:obtainFreshBeanFactory 详解(上)

Spring IOC源码:obtainFreshBeanFactory 详解(中)

Spring IOC源码:obtainFreshBeanFactory 详解(下)

Spring IOC源码:<context:component-scan>源码详解

Spring IOC源码:invokeBeanFactoryPostProcessors 后置处理器详解

Spring IOC源码:registerBeanPostProcessors 详解

Spring IOC源码:实例化前的准备工作

Spring IOC源码:finishBeanFactoryInitialization详解

Spring IoC源码:getBean 详解

Spring IoC源码:createBean( 上)

Spring IoC源码:createBean( 中)

Spring IoC源码:createBean( 下)

Spring IoC源码:finishRefresh 完成刷新详解

前言

上篇文章介绍了后置处理器BeanFactoryPostProcessor的注册、实例化及执行操作,这节介绍一下另外一个后置处理器BeanPostProcessor。前者是针对BeanFactory工厂对象进行增上改查操作,在bean实例化之前,我们可以修改其定义。后者是对实例化后的初始化环节前后对实例对象进行操作。

正文

进入refresh中的registerBeanPostProcessors(beanFactory)方法。该方法会将beanFactory工厂中所有BeanPostProcessor类型的BeanDefinition定义信息进行实例化注册,以便在bean的初始化环节中调用。

  protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
  }

PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this),见方法1详解

方法1:registerBeanPostProcessors

public static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
    //从BeanFactory工厂中获取BeanPostProcessor的实现类beanName
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
    //定义目标长度
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    //添加BeanPostProcessorChecker到beanFactory工厂中的beanPostProcessors集合中
    //这是个内部类,用来检查是否在bean的创建过程中,经过了所有本来应经过的后置处理器
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
    //实现了PriorityOrdered接口的后置处理器集合
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    //内部的后置处理器集合
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
    //实现了Ordered接口的后置处理器集合
    List<String> orderedPostProcessorNames = new ArrayList<>();
    //普通后置处理器集合
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    for (String ppName : postProcessorNames) {
      if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
        //实例化,获取对象
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        priorityOrderedPostProcessors.add(pp);
        //  内部类型
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
          internalPostProcessors.add(pp);
        }
      }
      //Ordered类型
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
        orderedPostProcessorNames.add(ppName);
      }
      else {
        nonOrderedPostProcessorNames.add(ppName);
      }
    }
    //对集合中的后置处理器进行排序
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    //加入到工厂集合中
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
    // Next, register the BeanPostProcessors that implement Ordered.
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    //将上述归类好的后置处理器进行实例化,并筛选出内部后置处理器
    for (String ppName : orderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      orderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
        internalPostProcessors.add(pp);
      }
    }
    //排序
    sortPostProcessors(orderedPostProcessors, beanFactory);
    //注册添加到集合中
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);
    // 处理普通的后置处理器
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String ppName : nonOrderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      nonOrderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
        internalPostProcessors.add(pp);
      }
    }
    //注册添加到集合中
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
    // 最后对所有的内部后置处理器进行排序,注册处理
    sortPostProcessors(internalPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, internalPostProcessors);
    //移除之前添加的ApplicationListenerDetector,将其放到最后端
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
  }

sortPostProcessors(priorityOrderedPostProcessors, beanFactory),方法我们在上篇文章中讲解《invokeBeanFactoryPostProcessors》中方法6


registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors),见方法2详解


beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)):


之前在refresh中的方法prepareBeanFactory添加过ApplicationListenerDetector,这里主要是排序,将该类型的后置处理器移到最后面来。

方法2:registerBeanPostProcessors

  private static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
    for (BeanPostProcessor postProcessor : postProcessors) {
      beanFactory.addBeanPostProcessor(postProcessor);
    }
  }
  public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
    Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
    // 如果之前容器中存在该对象,则移除
    this.beanPostProcessors.remove(beanPostProcessor);
    // 如果是InstantiationAwareBeanPostProcessor类型的后置处理器,则标识为已注册
    if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
      this.hasInstantiationAwareBeanPostProcessors = true;
    }
    // 如果是DestructionAwareBeanPostProcessor类型的后置处理器,则标识为已注册
    if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
      this.hasDestructionAwareBeanPostProcessors = true;
    }
    // 添加到集合末尾
    this.beanPostProcessors.add(beanPostProcessor);
  }


自定义

我们知道BeanPostProcessor实现类会在bean实例化后,初始化环节中进行调用,那我们如何自定义一个BeanPostProcessor 实现类并注册到工厂中呢?上篇文章我们演示了如何自定义BeanFactoryPostProcessor,其操作方法也是类型的;

1、自定义BeanPostProcessor

public class MyBeanPostProcessor implements BeanPostProcessor {
  @Override
  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    System.out.println("after:"+beanName);
    return null;
  }
  @Override
  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    System.out.println("before:"+beanName);
    return null;
  }
}

2、自定义上下文子类

通过拓展接口postProcessBeanFactory我们可以拿到工厂对象,并对其注册。

public class MyClassPathApplicationContext extends ClassPathXmlApplicationContext {
  public MyClassPathApplicationContext(String path){
    super(path);
  }
  @Override
  protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    beanFactory.addBeanPostProcessor(new MyBeanPostProcessor());
  }
}

3、编写入口

public class PersonTest {
  public static void main(String[] args) {
    MyClassPathApplicationContext applicationContext=new MyClassPathApplicationContext("application-scan.xml");
    StudentDao zdcDomain = (StudentDao) applicationContext.getBean("studentDao");
    System.out.println(zdcDomain);
  }
}

8b1a24620f86503c0436109ba7e13096_024c13090fa341c3956482ff4e1bcb45.png

总结

BeanPostProcessor和BeanFactoryPostProcessor都属于IOC后置处理器,只是两者操作的对象不一样,并且调用时间点也不一样;

BeanPostProcessor:在bean实例化后的初始化环节中进行调用,可以对实例化的bean对象进行操作。

BeanFactoryPostProcessor:在实例化前进行调用,可以修改bean的定义信息。

————————————————

版权声明:本文为CSDN博主「@猪大肠」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/weixin_45031612/article/details/127934441



目录
相关文章
|
3天前
|
XML Java 数据格式
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
这篇文章是Spring5框架的实战教程,主要介绍了如何在Spring的IOC容器中通过XML配置方式使用外部属性文件来管理Bean,特别是数据库连接池的配置。文章详细讲解了创建属性文件、引入属性文件到Spring配置、以及如何使用属性占位符来引用属性文件中的值。
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
|
3天前
|
XML Java 数据格式
Spring5入门到实战------4、IOC容器-Bean管理XML方式、集合的注入(二)
这篇文章是Spring5框架的实战教程,主题是IOC容器中Bean的集合属性注入,通过XML配置方式。文章详细讲解了如何在Spring中注入数组、List、Map和Set类型的集合属性,并提供了相应的XML配置示例和Java类定义。此外,还介绍了如何在集合中注入对象类型值,以及如何使用Spring的util命名空间来实现集合的复用。最后,通过测试代码和结果展示了注入效果。
Spring5入门到实战------4、IOC容器-Bean管理XML方式、集合的注入(二)
|
3天前
|
XML Java 数据格式
Spring5入门到实战------6、IOC容器-Bean管理XML方式(自动装配)
这篇文章是Spring5框架的入门教程,详细讲解了IOC容器中Bean的自动装配机制,包括手动装配、`byName`和`byType`两种自动装配方式,并通过XML配置文件和Java代码示例展示了如何在Spring中实现自动装配。
Spring5入门到实战------6、IOC容器-Bean管理XML方式(自动装配)
|
3天前
|
XML Java 数据格式
Spring5入门到实战------5、IOC容器-Bean管理(三)
这篇文章深入探讨了Spring5框架中IOC容器的高级Bean管理,包括FactoryBean的使用、Bean作用域的设置、Bean生命周期的详细解释以及Bean后置处理器的实现和应用。
Spring5入门到实战------5、IOC容器-Bean管理(三)
|
3天前
|
XML Java 数据格式
Spring5入门到实战------3、IOC容器-Bean管理XML方式(一)
这篇文章详细介绍了Spring框架中IOC容器的Bean管理,特别是基于XML配置方式的实现。文章涵盖了Bean的定义、属性注入、使用set方法和构造函数注入,以及如何注入不同类型的属性,包括null值、特殊字符和外部bean。此外,还探讨了内部bean的概念及其与外部bean的比较,并提供了相应的示例代码和测试结果。
Spring5入门到实战------3、IOC容器-Bean管理XML方式(一)
|
3天前
|
XML Java 数据格式
Spring5入门到实战------2、IOC容器底层原理
这篇文章深入探讨了Spring5框架中的IOC容器,包括IOC的概念、底层原理、以及BeanFactory接口和ApplicationContext接口的介绍。文章通过图解和实例代码,解释了IOC如何通过工厂模式和反射机制实现对象的创建和管理,以及如何降低代码耦合度,提高开发效率。
Spring5入门到实战------2、IOC容器底层原理
|
3天前
|
XML Java 数据格式
Spring5入门到实战------8、IOC容器-Bean管理注解方式
这篇文章详细介绍了Spring5框架中使用注解进行Bean管理的方法,包括创建Bean的注解、自动装配和属性注入的注解,以及如何用配置类替代XML配置文件实现完全注解开发。
Spring5入门到实战------8、IOC容器-Bean管理注解方式
|
3天前
|
XML Java 数据格式
Spring5入门到实战------2、IOC容器底层原理
这篇文章深入探讨了Spring5框架中的IOC容器,包括IOC的概念、底层原理、以及BeanFactory接口和ApplicationContext接口的介绍。文章通过图解和实例代码,解释了IOC如何通过工厂模式和反射机制实现对象的创建和管理,以及如何降低代码耦合度,提高开发效率。
Spring5入门到实战------2、IOC容器底层原理
|
4天前
|
Java Spring 容器
建模底层逻辑问题之以Spring IOC容器为例,使用因果法建模,如何操作
建模底层逻辑问题之以Spring IOC容器为例,使用因果法建模,如何操作
|
6天前
|
XML Dubbo Java
Spring之Ioc容器
该文章主要介绍了Spring框架中的IoC(Inversion of Control,控制反转)容器,包括IoC容器的概念、IoC容器在Spring中的实现以及IoC容器的基础包等内容。
Spring之Ioc容器