当前位置: 首页 > article >正文

10. Spring源码篇之BeanPostProcessor

简介

在Bean的创建过程中会有很多的后置处理器,例如实例化前、实例化后、初始化前、初始化后,属性填充等,这些都是通过BeanPostProcessor来实现的

那么既然每个Bean都有有这些生命周期,这些BeanPostProcessor肯定需要提前知道,并且实例化出来保存,而我们前面介绍来BeanDefinition的扫描,就可以把所有的Bean找出来,只要在实例化单例Bean之前把BeanPostProcessor实例化好就行了

在spring中就有这么一步注册BeanPostProcessor
就在AbstractApplicationContext#refresh方法中的一步registerBeanPostProcessors(beanFactory);

源码解析

public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

    // 通过getBeanNamesForType可以拿到所有的名字,因为这个时候还没有实例化,所以就拿到名字,里面使用isTypeMatch匹配
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();    // 找出所有实现 PriorityOrdered的BeanPostProcessor
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();    // 内置的BeanPostProcessor 如 MergedBeanDefinitionPostProcessor
    List<String> orderedPostProcessorNames = new ArrayList<>();    // 找出所有实现 Ordered的BeanPostProcessor
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();    // 没有任何排序的BeanPostProcessor
    
    for (String ppName : postProcessorNames) {
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            // 通过getBean获得BeanPostProcessor对象
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            priorityOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);    // 升序排序
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); // 注册BeanPostProcessors
    
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String ppName : orderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);         // 通过getBean获得BeanPostProcessor对象
        orderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);    // 升序排序
    registerBeanPostProcessors(beanFactory, orderedPostProcessors); // 注册BeanPostProcessors

    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String ppName : nonOrderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);  // 通过getBean获得BeanPostProcessor对象
        nonOrderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

    sortPostProcessors(internalPostProcessors, beanFactory);     // 升序排序 MergedBeanDefinitionPostProcessor排在最后
    registerBeanPostProcessors(beanFactory, internalPostProcessors);

    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); //注册 ApplicationListenerDetector 这个后续将
}

注册也会有个先后顺序,首先是实现了PriorityOrdered的排在前面,然后是实现Ordered接口的,再然后是没有现实排序接口的,最后是内置的例如MergedBeanDefinitionPostProcessor

这些BeanPostProcessor都会注册,通过beanFactory缓存起来

private final List<BeanPostProcessor> beanPostProcessors = new BeanPostProcessorCacheAwareList();

public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
    Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
    this.beanPostProcessors.remove(beanPostProcessor);
    this.beanPostProcessors.add(beanPostProcessor);
}

总结

从上面的代码中可以看出,在其他的单例Bean实例化之前,会先把BeanPostProcessor实例化好,并且排序

后面讲实例化前的BeanPostProcessor


欢迎关注,学习不迷路!


http://www.kler.cn/a/133011.html

相关文章:

  • 串口DMA接收不定长数据
  • 处理namespace问题:Namespace not specified for AGP 8.0.0
  • html + css 自适应首页布局案例
  • 【Linux系统编程】第四十六弹---线程同步与生产消费模型深度解析
  • cmake生成器表达式
  • 第9章 DIV+CSS布局作业
  • C/C++字符判断 2021年12月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析
  • 计算机网络———ipv6简解
  • 【观察】华为:数智世界“一触即达”,应对数智化转型“千变万化”
  • 在Linux系统上检测GPU显存和使用情况
  • 【AI视野·今日Robot 机器人论文速览 第六十二期】Wed, 25 Oct 2023
  • 定时任务 Spring Task
  • RAAGR2-Net:一种使用多个空间帧的并行处理的脑肿瘤分割网络
  • mfc140u.dll丢失的解决方法,以及针对每个解决mfc140u.dll丢失办法的优缺点
  • 苍穹外卖--实现照片上传
  • npm私有云
  • 在Uni-app中实现计时器效果
  • Android Studio 写一个Java调用c++ 的demo
  • springMvc中的拦截器【巩固】
  • 爱上C语言:操作符详解(下)
  • 08-黑马点评项目发布笔记和查看笔记功能的实现
  • 微软Surface/Surface pro笔记本电脑进入bios界面
  • el-table中el-popover失效问题
  • Spring中用了哪些设计模式
  • 电子学会C/C++编程等级考试2021年12月(一级)真题解析
  • Stream流常见操作