0
点赞
收藏
分享

微信扫一扫

Spring源码阅读----Spring IoC之registerBeanPostProcessors

朱小落 2021-09-25 阅读 61

概述

在invokeBeanFactoryPostProcessors方法执行之后,紧接着执行的是registerBeanPostProcessors,该方法是注册所有的 BeanPostProcessor,将所有实现了 BeanPostProcessor 接口的类加载到 BeanFactory 中。
BeanPostProcessor名字上跟BeanFactoryPostProcessor有点类似,那它们的功能是否也相似呢?对,它也是后置处理器,属于扩展点。
BeanPostProcessor 接口是 Spring 初始化 bean 时对外暴露的扩展点,Spring IoC 容器允许 BeanPostProcessor 在容器初始化 bean 的前后,添加自己的逻辑处理。在这边只是注册到 BeanFactory 中,具体调用是在 bean 初始化的时候。
在所有 bean 实例化时,执行初始化方法前会调用所有 BeanPostProcessor 的 postProcessBeforeInitialization 方法,执行初始化方法后会调用所有 BeanPostProcessor 的 postProcessAfterInitialization 方法。(通俗点来讲就是:比如Spring容器加载了bean之后,如果需要对所有的bean,或者某部分bean进行功能增强时,此时就可以采用一个叫做后置处理器的工具来对bean进行增强或扩展,Spring中的后置处理器也就是BeanPostProcessor接口)。
所以我们可以知道,BeanFactoryPostProcessor 是针对 BeanFactory 的扩展,主要用在 bean 实例化之前,读取 bean 的定义,并可以修改它;BeanPostProcessor 是针对 bean 的扩展,主要用在 bean 实例化之后,执行初始化方法前后,允许开发者对 bean 实例进行修改。

BeanPostProcessor 接口

public interface BeanPostProcessor {
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

registerBeanPostProcessors解析

    protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {

        //委托给PostProcessorRegistrationDelegate来执行registerBeanPostProcessors
        PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
    }

【源码解析】,PostProcessorRegistrationDelegate.registerBeanPostProcessors

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

        // 注释1. 从beanFactory获取所有实现BeanPostProcessor接口的类
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

        // Register BeanPostProcessorChecker that logs an info message when
        // a bean is created during BeanPostProcessor instantiation, i.e. when
        // a bean is not eligible for getting processed by all BeanPostProcessors.
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;

        //注释2. 新建一个BeanPostProcessorChecker(主要用于记录信息)对象,并添加到beanFactory中
        beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

        // Separate between BeanPostProcessors that implement PriorityOrdered,
        // Ordered, and the rest.
        // 注释3. 定义不同的列表集合用于区分: 
        // 注释3-1. 实现PriorityOrdered接口的BeanPostProcessor、实现Ordered接口的BeanPostProcessor、普通BeanPostProcessor以及Spring内部的BeanPostProcessor---internalPostProcessors:类型是 MergedBeanDefinitionPostProcessor
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
        List<String> orderedPostProcessorNames = new ArrayList<>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();

        //注释3-2. 遍历postProcessorNames, 将BeanPostProcessors按上面四种不同的列表区分开
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
                priorityOrderedPostProcessors.add(pp);
                //注释3-3. 如果ppName对应的Bean实例,也实现了MergedBeanDefinitionPostProcessor接口
                //则将ppName对应的Bean实例添加到internalPostProcessors
                if (pp instanceof MergedBeanDefinitionPostProcessor) {
                    internalPostProcessors.add(pp);
                }
            }
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            }
            else {
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        // First, register the BeanPostProcessors that implement PriorityOrdered.
        // 注释4. 首先,注册实现了 PriorityOrdered 接口的 BeanPostProcessors
        //注释4-1. 对priorityOrderedPostProcessors进行排序
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);

        //注释4-2. 对priorityOrderedPostProcessors进行注册
        registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

        // Next, register the BeanPostProcessors that implement Ordered.
        //注释5. 下一步,注册实现了 Ordered 接口的 BeanPostProcessors
        List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
        for (String ppName : orderedPostProcessorNames) {
                        //注释5-1. 获取 ppName对应的BeanPostProcessor实例对象
                        //并添加到orderedPostProcessors中,准备注册
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            orderedPostProcessors.add(pp);
                        //注释5-2.如果ppName对应的Bean实例也实现了MergedBeanDefinitionPostProcessor接口
                        //则将该实例添加到internalPostProcessors
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }

        //注释5-3. 排序、注册
        sortPostProcessors(orderedPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, orderedPostProcessors);

        // Now, register all regular BeanPostProcessors.
        // 注释6. 现在,注册常规 BeanPostProcessors
        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);

        // Finally, re-register all internal BeanPostProcessors.
        // 注释7. 最后, 重新注册所有内部BeanPostProcessors(相当于内部的BeanPostProcessor会被移到处理器链的末尾)
        // 这里看起来是重复注册了,但是每次注册调用的底层方法都会先移除已存在的 beanPostProcessor,然后再加进去,最后还是保存唯一
        sortPostProcessors(internalPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, internalPostProcessors);

        // Re-register post-processor for detecting inner beans as ApplicationListeners,
        // moving it to the end of the processor chain (for picking up proxies etc).
        // 注释9.创建一个ApplicationListenerDetector对象并且注册到容器,这就是前面计算beanProcessorTargetCount的值时加一的原因
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }

如上,具体步骤在注释处标明。详细来解析一下部分内容

注释4-1. 对priorityOrderedPostProcessors进行排序,类似前文的排序。
注释4-2. 对priorityOrderedPostProcessors进行注册(见源码解析1)

【源码解析1】 registerBeanPostProcessors

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

        for (BeanPostProcessor postProcessor : postProcessors) {
                        // 对每个bean都调用beanFactory的addBeanPostProcessor方法来注册
            beanFactory.addBeanPostProcessor(postProcessor);
        }
    }

BeanFactory的addBeanPostProcessor方法,在AbstractBeanFactory类中实现:

    public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
        Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
        // Remove from old position, if any
        //如果beanPostProcessor已经存在则移除(可以起到排序的效果,beanPostProcessor可能本来在前面,移除再添加,则变到最后面)
        this.beanPostProcessors.remove(beanPostProcessor);
        // Track whether it is instantiation/destruction aware
        if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
            //如果beanPostProcessor是InstantiationAwareBeanPostProcessor, 则将hasInstantiationAwareBeanPostProcessors设置为true
            //该变量用于指示beanFactory是否已注册过InstantiationAwareBeanPostProcessors
            this.hasInstantiationAwareBeanPostProcessors = true;
        }
        if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
            //如果beanPostProcessor是DestructionAwareBeanPostProcessor, 则将hasInstantiationAwareBeanPostProcessors设置为true
            //该变量用于指示beanFactory是否已注册过DestructionAwareBeanPostProcessor
            this.hasDestructionAwareBeanPostProcessors = true;
        }
        // Add to end of list
        //将beanPostProcessor添加到beanPostProcessors缓存
        this.beanPostProcessors.add(beanPostProcessor);
    }

所以这里可以看出该方法作用就是将入参的 BeanPostProcessor 添加到BeanFactory中的beanPostProcessors列表中,如果存在则删除,把它添加到末尾。这里也解释了注释7里面的疑问,不会重复注册。
hasInstantiationAwareBeanPostProcessors 和 hasDestructionAwareBeanPostProcessors 变量用于指示 beanFactory 是否已注册过 InstantiationAwareBeanPostProcessors 和 DestructionAwareBeanPostProcessor,这里暂时用不上,不过在之后的 IoC 创建过程会用到这两个变量。

BeanPostProcessor的实现类如何被使用

运行顺序如下:

  • Spring IOC容器实例化Bean
  • 调用BeanPostProcessor的postProcessBeforeInitialization方法
  • 调用bean实例的初始化方法
  • 调用BeanPostProcessor的postProcessAfterInitialization方法

通过测试来验证一下

  1. 创建一个TestBeanPostProcessor类,实现BeanPostProcessor接口
package com.zhlab.ssm.demo.web;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.PriorityOrdered;
import org.springframework.stereotype.Component;

/**
 * @ClassName TestBeanPostProcessor
 * @Description //TestBeanPostProcessor
 * @Author singleZhang
 * @Email 405780096@qq.com
 * @Date 2021/1/22 0022 下午 5:16
 **/
@Component
public class TestBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("TestBeanPostProcessor#postProcessBeforeInitialization");
        System.out.println(beanName);
        
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("TestBeanPostProcessor#postProcessAfterInitialization");
        System.out.println(beanName);

        return bean;
    }
}
  1. 修改启动类:
package com.zhlab.ssm.demo.web;

import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @ClassName App
 * @Description //App
 * @Author singleZhang
 * @Email 405780096@qq.com
 * @Date 2021/1/19 0019 下午 3:02
 **/
public class App {

    public static void main(String[] args) throws ClassNotFoundException {
        //XmlBeanFactory因为已经被废弃,这里使用了ClassPathXmlApplicationContext
        //XmlBeanFactory使用方式如下:
       // BeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("applicationContext.xml");
    }
}
  1. 运行main函数显示结果如下:

可以看到每个bean初始化前后都执行了postProcessBeforeInitialization、postProcessAfterInitialization方法。
那其中的执行顺序是如何的呢?
refresh方法中的registerBeanPostProcessors方法只是对这些BeanPostProcessors进行了注册,而执行的bean初始化是在refresh方法中的finishBeanFactoryInitialization方法里实现的。

这个具体在讲解finishBeanFactoryInitialization方法的时候展开讲,这里就引出来留个印象。其调用路径如下:

看,最终来到AbstractAutowireCapableBeanFactory类的 initializeBean方法,这就是bean的初始化方法,AbstractAutowireCapableBeanFactory类是DefaultListableBeanFactory类的父类,我们知道在前面的执行过程中,创建的beanFactory是一个DefaultListableBeanFactory对象
我们具体来看bean初始化的时候执行了什么(见源码解析2):
【源码解析2】 initializeBean方法

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
        // 注释1. securityManage 是一个安全管理器,判断其有无,然后执行实现了Aware系列接口的方法
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareMethods(beanName, bean);
                return null;
            }, getAccessControlContext());
        }
        else {
            // 如果没有 securityManage,方法里面校验了 bean 的类型,需要引用 Aware 接口
            // 对特殊的 bean 处理:Aware/ BeanClassLoader / BeanFactoryAware
            invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {

            // 注释2. 调用已经注册好的 beanPostProcessor 的 postProcessBeforeInitialization 方法
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        try {
            // 注释3. 调用执行初始化方法
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }
        if (mbd == null || !mbd.isSynthetic()) {
            //注释4.  调用已经注册好的 beanPostProcessor 的 postProcessAfterInitialization 方法
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

从这里可以看出在bean执行初始化之前,会遍历所有已经注册好的 beanPostProcessor,并执行postProcessBeforeInitialization 方法;而在初始化之后会遍历所有已经注册好的 beanPostProcessor,并执行postProcessorAfterInitialization方法。

※好了其他的不在这里展开,以免对阅读顺序产生干扰,我们阅读源码时需要抓住主线走,等主线完成后,再回顾到做了标记的分支,逐个再击破。

总结

这里我们了解了registerBeanPostProcessors 方法,其主要是对各类BeanPostProcessors进行注册,围绕 BeanPostProcessor 接口,这里做的工作只是注册,具体实现在后边finishBeanFactoryInitialization方法才会使用到 这些BeanPostProcessor 接口的实现类。
postProcessBeforeInitialization、postProcessAfterInitialization方法分别在bean对象初始化的前后执行。
BeanPostProcessor 实现类和 BeanFactoryPostProcessor 实现类一样,也可以通过实现 PriorityOrdered、Ordered 接口来调整自己的优先级。
两者有些区别,注册BeanFactoryPostProcessor的实例,需要上下文执行refresh
BeanFactoryPostProcessor的处理对象时BeanFactory,它可以增强BeanFactory获取bean实例或定义等,并可以修改bean的属性,它发生在bean实例化之前,对bean的处理功能更强;BeanPostProcessor的处理对象时Bean,它体现的是AOP的思想,通过它来切入bean的初始化前后的增强处理,它默认是会对整个Spring容器中所有的bean进行处理,也可以自定义实现对某个bean的处理,它发生在bean实例化之后。

举报

相关推荐

0 条评论