备战面试日记(4.2.8)- (框架.Spring【八】之Spring IOC 源码registerBeanPostProcessors())

本人本科毕业,21届毕业生,一年工作经验,简历专业技能如下,现根据简历,并根据所学知识复习准备面试。

记录日期:2022.1.4

大部分知识点只做大致介绍,具体内容根据推荐博文链接进行详细复习。

框架原理 - Spring(八)之Spring IOC 源码registerBeanPostProcessors()

AbstractApplicationContext#registerBeanPostProcessors()

本方法会注册所有的 BeanPostProcessor,将所有实现了 BeanPostProcessor 接口的类加载到 BeanFactory 中。

BeanPostProcessor 接口是 Spring 初始化 bean 时对外暴露的扩展点,Spring IoC 容器允许 BeanPostProcessor 在容器初始化 bean 的前后,添加自己的逻辑处理。在 registerBeanPostProcessors 方法只是注册到 BeanFactory 中,具体调用是在 bean 初始化的时候。

具体的调用时机是在所有 bean 实例化时,执行初始化方法前会调用所有 BeanPostProcessorpostProcessBeforeInitialization 方法,在执行初始化方法后会调用所有 BeanPostProcessorpostProcessAfterInitialization 方法。

话不多说,直接来看一下代码实现:

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    // 注册BeanPostProcessor
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

registerBeanPostProcessors()

注册BeanPostProcessor的具体过程,直接来看源码,有几个注意点写在该代码块下方

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

    /*	【注释翻译】
    	警告:尽管此方法的主体似乎可以很容易地重构,以避免使用多个循环和多个列表,
    	但在处理器名称上使用多个列表和多次传递是有意的。我们必须确保遵守优先订购和订购处理器的合同。
    	具体来说,我们不能导致处理器被实例化(通过getBean()调用)或以错误的顺序在ApplicationContext中注册。
    	
    	在提交更改此方法的请求请求(PR)之前,
    	请查看所有涉及对后处理程序RegistrationLegate进行更改的被拒绝的PR列表,
    	以确保您的提案不会导致重大更改:
    	https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22
    */
    
    // 1. 找出所有实现BeanPostProcessor接口的类,!具体见下文介绍!
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

    /*	【注释翻译】
    	注册BeanPostProcessorChecker,当BeanPostProcessor实例化期间创建bean时,
    	即当一个bean不符合由所有BeanPostProcessor处理的条件时,它会记录一条信息消息。
    */
    // BeanPostProcessor的目标计数
    // beanFactory.getBeanPostProcessorCount() 是 获取已经注册的BeanPostProcessor个数
    
    // 这里 +1 的原因是此方法最后会添加一个BeanPostProcessorChecker的类,!具体见下文介绍!
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    // 2. 添加BeanPostProcessorChecker(主要用于记录信息)到beanFactory中
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

    // 【注释翻译】在实现PriorityOrdered、Ordered和rest的BeanPostProcessor之间进行分离
    // 3. 定义不同集合用于区分四种不同BeanPostProcessor
    // 3.1 存放实现了PriorityOrdered接口的BeanPostProcessor集合
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    // 3.2 存放spring内部的BeanPostProcessor集合
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
    // 3.3 存放实现了Ordered接口的BeanPostProcessor的beanName集合
    List<String> orderedPostProcessorNames = new ArrayList<>();
    // 3.4 存放普通的BeanPostProcessor的beanName集合
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    // 4. 遍历遍历postProcessorNames, 将BeanPostProcessors放在对应的集合中
    for (String ppName : postProcessorNames) {
        // 4.1 如果ppName对应的Bean实例实现了PriorityOrdered接口
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            // 4.1.1 添加到priorityOrderedPostProcessors集合中
            priorityOrderedPostProcessors.add(pp);
            // 4.2 如果ppName对应的Bean实例也实现了MergedBeanDefinitionPostProcessor接口
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                // 4.2.1 添加到internalPostProcessors集合中
                internalPostProcessors.add(pp);
            }
        }
        // 4.3 如果ppName对应的Bean实例实现了Ordered接口
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            // 4.3.1 添加到orderedPostProcessorNames集合中
            orderedPostProcessorNames.add(ppName);
        }
        // 4.4 否则就是普通的BeanPostProcessor
        else {
            // 4.4.1 添加到nonOrderedPostProcessorNames集合中
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // 【注释翻译】 首先,注册实现PriorityOrdered的BeanPostProcessor
    // 5. 注册实现PriorityOrdered接口的BeanPostProcessor
    // 5.1 对priorityOrderedPostProcessors进行排序
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    // 5.2 注册priorityOrderedPostProcessors
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    // 【注释翻译】接下来,注册实现Ordered的BeanPostProcessor
    // 6. 注册实现Ordered接口的BeanPostProcessor
    // 6.1 创建存放实现Ordered接口的BeanPostProcessor集合
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String ppName : orderedPostProcessorNames) {
        // 6.2 拿到ppName对应的BeanPostProcessor实例对象
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        // 6.3 将对应的BeanPostProcessor实例对象添加到集合中,准备注册
        orderedPostProcessors.add(pp);
        // 6.4 如果该bean也实现了MergedBeanDefinitionPostProcessor接口,则添加到internalPostProcessors
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    // 6.5 对orderedPostProcessors进行排序
    sortPostProcessors(orderedPostProcessors, beanFactory);
    // 6.6 注册orderedPostProcessors
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

    // 【注释翻译】现在,注册所有常规BeanPostProcessor
    // 7. 注册所有常规的BeanPostProcessors(过程与6类似)
    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);

    // 【注释翻译】最后,重新注册所有内部BeanPostProcessor
    // 8. 最后, 重新注册所有内部BeanPostProcessors(相当于内部的BeanPostProcessor会被移到处理器链的末尾)\
    // 8.1 对internalPostProcessors进行排序
    sortPostProcessors(internalPostProcessors, beanFactory);
    // 8.2 注册internalPostProcessors
    registerBeanPostProcessors(beanFactory, internalPostProcessors);

    // 【注释翻译】将用于检测内部bean的后处理器重新注册为ApplicationListener,将其移动到处理器链的末端(用于拾取代理等)
    // 重新注册ApplicationListenerDetector(跟8类似,主要是为了移动到处理器链的末尾)
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

其中注册BeanPostProcessor的方法registerBeanPostProcessors()实现如下:

private static void registerBeanPostProcessors(
    ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

    if (beanFactory instanceof AbstractBeanFactory) {
        // Bulk addition is more efficient against our CopyOnWriteArrayList there
        ((AbstractBeanFactory) beanFactory).addBeanPostProcessors(postProcessors);
    }
    else {
        for (BeanPostProcessor postProcessor : postProcessors) {
            beanFactory.addBeanPostProcessor(postProcessor);
        }
    }
}

registerBeanPostProcessors()中postProcessorNames

首先讨论一下 postProcessorNames 中获取的beanNames。

String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

它包括 spring自己注册的bean 以及 开发者自己导入的bean

spring默认的3个类型为BeanPostProcessor的bean

默认情况下应该只有三个,是在初始化 AnnotatedBeanDefinitionReader 时注册的spring加载流程之AnnotatedBeanDefinitionReader

  • AutowiredAnnotationBeanPostProcessor
  • RequiredAnnotationBeanPostProcessor
  • CommonAnnotationBeanPostProcessor

自定义的类型为 BeanPostProcessor 的bean

  1. 可以自定义bean(需要添加元注解,能够被扫描注册进容器)实现BeanPostProcessor接口,这时候postProcessorNames就会出现自定义bean的beanName。
  2. 通过@Enable注解导入,例如在使用 AOP 时用到了@EnableAspectJAutoProxy@EnableAsync注解,spring就会注册以下两个额外的bean。
  • AsyncAnnotationBeanPostProcessor
  • AutoProxyCreator

registerBeanPostProcessors()中beanProcessorTargetCount

再讨论一下 beanProcessorTargetCount的计算。

int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;

它的值为: BeanPostProcessor 的bean数量 + 已经注册的BeanPostProcessor的bean数量 + 一个BeanPostProcessorChecker

  1. BeanPostProcessor 的bean数量是指:
// postProcessorNames的长度,这个上面说过了
postProcessorNames.length;
  1. 已经注册的BeanPostProcessor的bean数量是指:

通过执行beanFactory.addBeanPostProcessor(bpp)添加到
List<BeanPostProcessor> beanPostProcessors = new ArrayList();中去的BeanPostProcessors

// 获取已经注册的BeanPostProcessor个数
beanFactory.getBeanPostProcessorCount();

此时的spring默认有3个已经被注册,我们来了解一下这三个是什么时候添加进去的:

  • ApplicationContextAwareProcessor
  • ApplicationListenerDetector
  • ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor
private final List<BeanPostProcessor> beanPostProcessors = new BeanPostProcessorCacheAwareList();

他们的添加方式如下:

  1. 执行spring加载流程prepareBeanFactory(beanFactory)时添加了ApplicationContextAwareProcessorApplicationListenerDetector这两个后置处理器;这个代码可以自己去源代码里面找可以找到。
  2. 还有一个是在实行spring加载流程invokeBeanFactoryPostProcessors(beanFactory)添加的;这个加载时通过ConfigurationClassPostProcessor.postProcessBeanFactory()中添加的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

舍其小伙伴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值