2

spring5源码-内置的后置处理器PostProcess加载源码解析

 2 years ago
source link: https://xiaomozhang.github.io/2021/10/15/spring5-postprocess-source-code-analysis/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

一. 研究目标: 解析spring如何加载配置类

我们经常会在一个类上打上@Configuration, @Component, @Bean等. 带有这些注解的类, 我们在spring启动的时候,是如何被加载的呢?

下面就以此为目的,分析spring源码. 本节的内容是对上一节内容的实战分析, 同时更加详细的解读spring源码

spring-context-run-process.png
spring-context-run-process.png

我们知道, spring启动的时候做了3件事, 就是上面的三件事.

第一件事: 调用this()自身的无参构造函数. 初始化了BeanDefinitionReader和BeanDefinitionScanner, 同时初始化了很多spring的原始后置处理器, 这些处理器是用来加载在定义bean的
第二件事: 调用register(…)
第三件事: refresh(…) 这里包含了整个ioc创建bean的全生命周期

二. 自定义配置类

我们先定义好要分析加载的配置类

package com.lxl.www.iocbeanlifecicle;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * 这是一个配置类,
 * 在配置类里面定义了扫描的包路径com.lxl.www.iocbeanlifecicle
 * 这是会将这个包下配置了注解的类扫描到ioc容器里面,成为一个成熟的bean
 */
@Configuration
@ComponentScan(basePackages = {"com.lxl.www.iocbeanlifecicle"})
public class MainConfig {
}

这个配置类很简单, 使用@ComponentScan注解指定了扫描的包. @Configuration指定当前是一个配置类

package com.lxl.www.iocbeanlifecicle;


import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainStarter {
    public static void main(String[] args) {
        // 第一步: 通过AnnotationConfigApplicationContext读取一个配置类
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
        //context.addBeanFactoryPostProcessor();
        Car car = (Car) context.getBean("car");
        System.out.println(car.getName());
        context.close();
    }
}

在main里, 通过AnnotationConfigurationApplicationContext读取配置类MainConfig.class.

配置类被传进来以后, 到底是怎么被解析的呢? 这就是我们分析的线索

始终不要忘记我们的整体架构图. 对照这个图来分析. 思路更清晰. 整体内容讲解在这里:spring5源码 - ioc加载整体流程详解

annotationConfigApplicationContext-run-process.png
annotationConfigApplicationContext-run-process.png

下面, 从入口进入. 我们的入口就是这里

new AnnotationConfigApplicationContext(MainConfig.class);

下面进入AnnotationConfigApplicationContext的构造方法

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
        // 进入构造函数, 首先调用自身的构造方法this();
        // 调用自身的构造方法之前, 要先调用父类的构造方法
        this();
        // register配置注册类
        register(componentClasses);
        // ioc容器shua新接口--非常重要
        refresh();
    }

三、读取配置类后置处理器ConfigurationClassPostProcessor

3.1 this()无参构造函数

public AnnotationConfigApplicationContext() {
        /**
         * 创建了一个Bean定义的读取器.
         * 完成了spring内部BeanDefinition的注册(主要是后置处理器)
         * 读取了很多spring自定义的配置(主要是后置处理器). 这些类都是spring 的原始类(也就是创世纪的类).
         */
        this.reader = new AnnotatedBeanDefinitionReader(this);

        /**
         * 创建BeanDefinition扫描器
         * 可以用来扫描包或者类, 进而转换为bd
         *
         * Spring默认的扫描包不是这个scanner对象
         * 而是自己new的一个ClassPathBeanDefinitionScanner
         * Spring在执行工程后置处理器ConfigurationClassPostProcessor时, 去扫描包时会new一个ClassPathBeanDefinitionScanner
         *
         * 这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法
         * 通过调用context.scan("package name");扫描处理配置类
         * 扫描
         */
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }

在初始化AnnotatedBeanDefinitionReader(this);的时候, 注册了很多后置处理器

/**
     * Register all relevant annotation post processors in the given registry.
     * @param registry the registry to operate on
     * @param source the configuration source element (already extracted)
     * that this registration was triggered from. May be {@code null}.
     * @return a Set of BeanDefinitionHolders, containing all bean definitions
     * that have actually been registered by this call
     */
    public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
            BeanDefinitionRegistry registry, @Nullable Object source) {

        // 获取到beanFactory
        DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
        /**
         * 判断beanFactory中是否有AnnotationAwareOrderComparator和ContextAnnotationAutowireCandidateResolver
         * 没有则添加
         */
        if (beanFactory != null) {
            if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
                beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
            }
            if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
                beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
            }
        }

        // BeanDefinitionHolder: 为BeanDefinition设置名字和别名
        Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

        // 如果registry中没有ConfigurationClassPostProcessor配置类后置处理器, 就添加一个
        if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
            def.setSource(source);
            // 构建BeanDefinitionHolder, 并添加到beanDefs
            beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        // 如果rigistry中, 没有AutowiredAnnotationBeanPostProcessor  Autowired注解bean的后置处理器, 则添加一个
        if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
            def.setSource(source);
            // 构建BeanDefinitionHolder, 并添加到beanDefs
            beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
        // 检查对JSR-250的支持, 如果rigistry中没有 CommonAnnotationBeanPostProcessor 通用注解后置处理器, 则添加一个
        if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
            def.setSource(source);
            // 构建BeanDefinitionHolder, 并添加到beanDefs
            beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
        // 检查对jpa的支持, 如果不包含 internalPersistenceAnnotationProcessor, 持久化注解处理器, 就添加一个
        if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition();
            try {
                def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
                        AnnotationConfigUtils.class.getClassLoader()));
            }
            catch (ClassNotFoundException ex) {
                throw new IllegalStateException(
                        "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
            }
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        // 检查对事件监听的支持, 如果不包含事件监听处理器 internalEventListenerProcessor, 就添加一个
        if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
        }

        // 如果不包含事件监听工厂处理器 internalEventListenerFactory , 就添加一个
        if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
        }

        return beanDefs;
    }

我们看到, 注册了6个原始bean, 这些bean是spring自己提前定义好的, 他们的加载是整个spring的基础. 用于解析spring 中其他的类

而这一次我们要读取配置, 所以重点关注的是下面这个类

ConfigurationClassPostProcessor.class

这里还有很多其他的原始类被注册了, 但我们的目标是分析配置类是如何被读取的, 所以, 其他的先忽略, 只看ConfigurationClassPostProcessor.

3.2 ConfigurationClassPostProcessor的继承结构

configurationClassPostProcessor-diagram.png
configurationClassPostProcessor-diagram.png

可以看到ConfigurationClassPostProcessor是同时实现了BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor. 这一点我们需要记住, 后面会使用到

2.3 ConfigurationClassPostProcessor是如何被注册的

// 如果registry中没有ConfigurationClassPostProcessor配置类后置处理器, 就添加一个
        if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
            def.setSource(source);
            // 构建BeanDefinitionHolder, 并添加到beanDefs
            beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

首先,构建了一个RootBeanDefinition. 然后调用了registerPostProcessor方法, 三个入参分别是

registry: BeanDefinitionRegistry注册器, 用于注册BeanDefinition
def: 刚刚构建的RootBeanDefinition
CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME: 构建BeanDefinition使用的beanName是org.springframework.context.annotation.internalConfigurationAnnotationProcessor

然后调用registerPostProcessor方法

@Override
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
            throws BeanDefinitionStoreException {

        Assert.hasText(beanName, "Bean name must not be empty");
        Assert.notNull(beanDefinition, "BeanDefinition must not be null");

        if (beanDefinition instanceof AbstractBeanDefinition) {
            try {
                ((AbstractBeanDefinition) beanDefinition).validate();
            }
            catch (BeanDefinitionValidationException ex) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                        "Validation of bean definition failed", ex);
            }
        }

        // 从BeanDefinition的一级缓存BeanDefinitionMap中读取BeanDefinition对象, 判断是否已经存在
        BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
        if (existingDefinition != null) {
            // 判断是否允许BeanDefinition重写
            if (!isAllowBeanDefinitionOverriding()) {
                throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
            }
            else if (existingDefinition.getRole() < beanDefinition.getRole()) {
                // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
                if (logger.isInfoEnabled()) {
                    logger.info("Overriding user-defined bean definition for bean '" + beanName +
                            "' with a framework-generated bean definition: replacing [" +
                            existingDefinition + "] with [" + beanDefinition + "]");
                }
            }
            else if (!beanDefinition.equals(existingDefinition)) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Overriding bean definition for bean '" + beanName +
                            "' with a different definition: replacing [" + existingDefinition +
                            "] with [" + beanDefinition + "]");
                }
            }
            else {
                if (logger.isTraceEnabled()) {
                    logger.trace("Overriding bean definition for bean '" + beanName +
                            "' with an equivalent definition: replacing [" + existingDefinition +
                            "] with [" + beanDefinition + "]");
                }
            }
            // 以上情况都没有限制, 重置一级缓存的bean定义
            this.beanDefinitionMap.put(beanName, beanDefinition);
        }
        else {
            // 处理循环引用的问题
            if (hasBeanCreationStarted()) {
                // Cannot modify startup-time collection elements anymore (for stable iteration)
                synchronized (this.beanDefinitionMap) {
                    this.beanDefinitionMap.put(beanName, beanDefinition);
                    List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
                    updatedDefinitions.addAll(this.beanDefinitionNames);
                    updatedDefinitions.add(beanName);
                    this.beanDefinitionNames = updatedDefinitions;
                    removeManualSingletonName(beanName);
                }
            }
            else {
                // Still in startup registration phase
                this.beanDefinitionMap.put(beanName, beanDefinition);
                this.beanDefinitionNames.add(beanName);
                removeManualSingletonName(beanName);
            }
            this.frozenBeanDefinitionNames = null;
        }

        if (existingDefinition != null || containsSingleton(beanName)) {
            resetBeanDefinition(beanName);
        }
        else if (isConfigurationFrozen()) {
            clearByTypeCache();
        }
    }

这里面的关键代码是标红的部分, 将ConfigurationClassPostProcessor放入到了beanDefinitionMap里面

下面的else是处理循环引用的问题, 暂时先不要看. 后面有专门的章节讲解循环引用.

2.4 对照整体框架, 我们知道ConfigurationClassPostProcessor被解析成beanDefinition放入到BeanDefinitionMap中了

configurationClassPostProcessor-beanDefinitionMap.png
configurationClassPostProcessor-beanDefinitionMap.png

ConfigurationClassPostProcessor是一个工具类, 这个类的作用是解析配置类.

工具类有了, 那么还得有主角呀, 那就是我们上面的配置类. 下面看看配置类的加载

2.5 初始化ClassPathBeanDefinitionScanner

在this()构造方法里, 还初始化了ClassPathBeanDefinitionScanner, 这里只说一句.

this.scanner = new ClassPathBeanDefinitionScanner(this);

我们在扫描配置类的时候, 确实使用的是ClassPathBeanDefinitionScanner, 但是, 不是this.scanner对象. 而是自己new的一个ClassPathBeanDefinitionScanner.

这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法

通过调用context.scan(“package name”);扫描处理配置类

使用方式如下:

public static void main(String[] args) {
        // 第一步: 通过AnnotationConfigApplicationContext读取一个配置类
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
        context.scan("package");
        Car car = (Car) context.getBean("car");
        System.out.println(car.getName());
        context.close();
    }

到目前为止完成了后置处理器注册为BeanDefinition

四. 读取自定义配置类MainConfig

注册配置类,入口自然是这里了

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
        // 进入构造函数, 首先调用自身的构造方法this();
        // 调用自身的构造方法之前, 要先调用父类的构造方法
        this();
        // register配置注册类
        register(componentClasses);
        // ioc容器shua新接口--非常重要
        refresh();
    }

跟踪进去找到doRegisterBean(…)方法

private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
            @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
            @Nullable BeanDefinitionCustomizer[] customizers) {

        // 将入参的配置类beanClass构建成AnnotatedGenericBeanDefinition对象
        AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
        if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
            return;
        }

        abd.setInstanceSupplier(supplier);
        // 读取配置类的元数据
        ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
        abd.setScope(scopeMetadata.getScopeName());
        String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

        // 处理主类通用定义注解
        AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
        if (qualifiers != null) {
            for (Class<? extends Annotation> qualifier : qualifiers) {
                if (Primary.class == qualifier) {
                    abd.setPrimary(true);
                }
                else if (Lazy.class == qualifier) {
                    abd.setLazyInit(true);
                }
                else {
                    abd.addQualifier(new AutowireCandidateQualifier(qualifier));
                }
            }
        }
        if (customizers != null) {
            for (BeanDefinitionCustomizer customizer : customizers) {
                customizer.customize(abd);
            }
        }
        // 将MainConfig.java配置类进行解析.放到BeanDefinitionHolder
        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
        definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
        BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
    }

重点就是红色这句话, 其他可以略过, 因为我们的配置类很简单, 直接看BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
我们找到 registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());方法, 进入到DefaultListableBeanFactory查看方法, 这个方法之前我们已经调用过一次

就是在注册ConfigurationClassPostProcessor的时候, 我们需要将其解析为BeanDefinition然后放到BeanDefinitionMap中, 这里也是一样的, 将我们的配置类MainConfig解析成BeanDefinition放入到BeanDefinitionMap中.

这里的代码在整个框架中处于什么位置呢? 将MainConfig解析为BeanDefinition放入到BeanDefinitionMap中

spring-context-run-process.png
spring-context-run-process.png

以上两步, 一个是将ConfigurationClassPostProcessor配置类后置处理器, 也就是解析配置的工具类, 解析成BeanDefinition放入到BeanDefinitionMap中

另一个是将我们的目标配置类MainConfig加载到内存, 组装成BeanDefinition放入到BeanDefinitionMap中.

mainConfig-init-process.png
mainConfig-init-process.png

五. 调用bean工厂的后置处理器invokeBeanFactoryPostProcessors(beanFactory)

在refresh()中有很多步骤, 我们重点来看invokeBeanFactoryPostProcessors(beanFactory);

/**
     * refresh是spring最核心的方法, 里面包含了整个spring ioc的全过程, 包括spring加载bean到销毁bean的全过程
     * 学习spring, 就是学习里面的13个方法, 如果13个方法都学完了, 基本上就打通了
     * @throws BeansException
     * @throws IllegalStateException
     */
    @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // 1. 准备刷新上下文环境
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            //2. 获取告诉子类初始化bean工厂, 不同工厂不同实现
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();


            // Prepare the bean factory for use in this context.
            //3. 对bean工厂进行填充属性
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                // 4. 留个子类去实现该接口
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                /*
                 *
                 * 调用bean工厂的后置处理器
                 * 我们之前在Reader的时候读取了很多创世纪的PostProcessor后置处理器.
                 * 这里要调用bean工厂的后置处理器. 这么多创世纪的PostProcessor, 只有一个PostProcessor实现了
                 * BeanFactoryPostProcessor. 那个类就是 ConfigurationClassPostProcessor
                 * 前面已经将ConfigurationClassPostProcessor放入到BeanDefinitionMap中了,
                 * 对应的BeanDefinitionName 是 internalConfigurationAnnotationProcessor
                 *
                 *
                 *
                 */
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                // 注册bean后置处理器
                registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                // 初始化国际化资源处理器
                initMessageSource();

                // Initialize event multicaster for this context.
                // 创建事件多播放器
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                // 这个方法通用也是留个子类实现的, spring boot也是从这个方法进行启动
                onRefresh();

                // Check for listener beans and register them.
                // 将事件监听器注册到多播放器上
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                // 实例化剩余的单实例bean
                /**
                 * 这个方法就是循环遍历BeanDefinitionMap, 调用getBean, 去生产bean
                 */
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                //最后容器刷新 发布刷新时间(spring cloud是从这里启动的 )
                finishRefresh();
            }

            ........
    }

invokeBeanFactoryPostProcessors(beanFactory);看名字, 调用的是Bean工厂的后置处理器, 我们在第二部分说了, 初始化的时候初始化了很多spring原生的后置处理器, 这么多后置处理器, 其实,
只有一个后置处理器实现了BeanFactoryPostProcessor, 它就是ConfigurationClassPostProcessor, 还记得上面让大家记住的结构图么, 拿下来, 再看一遍.
这里调用的时候, 原生处理器只会调用ConfigurationClassPostProcessor.

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        /**
         * 获取两处存储BeanFactoryPostProcessor的对象, 传入供接下来调用
         * 1. 当前bean工厂
         * 2. 和我们自己调用addBeanFacoryPostProcessor自定义BeanFactoryPostProcessor
         *
         * 参数: getBeanFactoryPostProcessors() 传了一个工厂的后置处理器的List, 这个时候list是空的
         * getBeanFactoryPostProcessors()里面的值是怎么来的呢?
         * 通过在自定义main方法中调用context.addBeanFactoryPostProcessor(...);来添加
         *
         * public static void main(String[] args) {
         *         // 第一步: 通过AnnotationConfigApplicationContext读取一个配置类
         *         AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
         *         context.addBeanFactoryPostProcessor(...);
         *         Car car = (Car) context.getBean("car");
         *         System.out.println(car.getName());
         *         context.close();
         * }
         */
        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

        // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
        // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
        if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }
    }

这里要调用bean工厂的后置处理器了. 看上面的注释, 注释写的很清晰.

在调用PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());的时候调用了getBeanFactoryPostProcessors()方法.

public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
       return this.beanFactoryPostProcessors;
   }

getBeanFactoryPostProcessors() 返回的是一个工厂的后置处理器的List, 这个时候list是空的
getBeanFactoryPostProcessors()里面的值是怎么来的呢?
通过在自定义main方法中调用context.addBeanFactoryPostProcessor(…);来添加. 也就是通过main 方法手动添加的beanFactory

public static void main(String[] args) {
           // 第一步: 通过AnnotationConfigApplicationContext读取一个配置类
           AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
           context.addBeanFactoryPostProcessor(...);
           Car car = (Car) context.getBean("car");
           System.out.println(car.getName());
           context.close();
    }

接下来重点来了. PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); 方法实现一共分为两大步:

第一步: 调用所有实现了 BeanDefinitionRegistryPostProcessor 接口的bean定义. (BeanDefinitionRegistryPostProcessor带注册功能的后置处理器)
第二步: 调用BeanFactoryPostProcessor Bean工厂的后置处理器

第一步: 调用所有实现了 BeanDefinitionRegistryPostProcessor 接口的bean定义.

来看看源码是如何定义的. 重点看代码的注释, 每一部分的功能都有明确标出, 注释写的很详细

public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

        /**
         * 首先,调用BeanDefinitionRegistryPostProcessors的后置处理器
         * 定义已处理的后置处理器
         */
        // Invoke BeanDefinitionRegistryPostProcessors first, if any.
        Set<String> processedBeans = new HashSet<>();

        /**
         * 这里一共分为两大步:
         * 第一步: 调用所有实现了 BeanDefinitionRegistryPostProcessor 接口的bean定义. (BeanDefinitionRegistryPostProcessor带注册功能的后置处理器)
         * 第二步: 调用BeanFactoryPostProcessor Bean工厂的后置处理器
         */

        /**********************第一步: 调用所有实现了BeanDefinitionRegistryPostProcessor接口的bean定义  begin****************************/
        // 判断beanFactory是否实现了BeanDefinitionRegistry, 实现了该结构就有注册和获取Bean定义的能力
        if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    registryProcessors.add(registryProcessor);
                }
                else {
                    regularPostProcessors.add(postProcessor);
                }
            }

            // Do not initialize FactoryBeans here: We need to leave all regular beans
            // uninitialized to let the bean factory post-processors apply to them!
            // Separate between BeanDefinitionRegistryPostProcessors that implement
            // PriorityOrdered, Ordered, and the rest.
            /**
             * 这是一个集合, 存马上即将要被调用的BeanDefinitionRegistryPostProcessor
             */
            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
            // 第一步, 调用实现了PriorityOrdered的BeanDefinitionRegistryPostProcessors
            // 在所有创世纪的后置处理器中, 只有 internalConfigurationAnnotationProcessor 实现了 BeanDefinitionRegistryPostProcessors 和 PriorityOrdered
            // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 判断beanFactory是否实现了PriorityOrdered接口. 如果实现了,是最优先调用.
                // 在整个加载过程中,会调用四次BeanDefinitionRegistryPostProcessor, 而实现了PriorityOrdered的接口最先调用
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    // 调用beanFactory.getBean实例化创世界的类ppName
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            /**
             * 第一次调用BeanDefinitionRegistryPostProcessors
             * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor
             * 用于进行bean定义的加载 比如我们的包扫描 @import 等
             */
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // 处理完了,清空currentRegistryProcessors
            currentRegistryProcessors.clear();


            // 第二步: 调用实现 Ordered 的 BeanDefinitionRegistryPostProcessors。
            // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 这时实现了PriorityOrdered.class的postProcessor就不会再被加载进来了, 因为processedBeans.contains(ppName) == true
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    // 将其放入到currentRegistryProcessors, 马上就要被调用
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }

            // 对所有的处理器进行排序. 调用了Ordered的方法, 会返回排序(一个数字), 然后根据数字排序即可
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);

            /**
             * 第二次调用BeanDefinitionRegistryPostProcessors
             * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor
             * 用于进行bean定义的加载 比如我们的包扫描 @import 等
             */
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();


            // 第三步. 调用没有实现任何优先级接口的 BeanDefinitionRegistryPostProcessor
            // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
            boolean reiterate = true;
            while (reiterate) {
                reiterate = false;
                // 获取
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    // 已处理过的postProcessor不再处理
                    if (!processedBeans.contains(ppName)) {
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                        reiterate = true;
                    }
                }
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                /**
                 * 第三次调用BeanDefinitionRegistryPostProcessors
                 * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor
                 * 用于进行bean定义的加载 比如我们的包扫描 @import 等
                 */
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();
            }

            // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
            /*
             * 调用bean工厂的后置处理器
             * registryProcessors: 带有注册功能的bean工厂的后置处理器
             * regularPostProcessors: 不带注册功能的bean工厂的后置处理器
             */
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        }

        else {
            /*
             * 如果当前的beanFactory没有实现BeanDefinitionRegistry 说明没有注册Bean定义的能力
             * 那么就直接调用 BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法
             */

            // Invoke factory processors registered with the context instance.
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }

        /**********************第一步: 调用所有实现了BeanDefinitionRegistryPostProcessor接口的bean定义  end****************************/

        /**********************第二步: 调用BeanFactoryPostProcessor Bean工厂的后置处理器  begin****************************/

        // Do not initialize FactoryBeans here: We need to leave all regular beans
        // uninitialized to let the bean factory post-processors apply to them!
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

        // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
        // Ordered, and the rest.
        // 优先排序的后置处理器
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        List<String> orderedPostProcessorNames = new ArrayList<>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        for (String ppName : postProcessorNames) {
            if (processedBeans.contains(ppName)) {
                // skip - already processed in first phase above
            }
            else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            }
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            }
            else {
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        // 首先, 调用有优先级排序的后置处理器
        // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        // 第二, 调用实现了Ordered排序的后置处理器
        // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
        for (String postProcessorName : orderedPostProcessorNames) {
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

        // 最后, 调用没有实现任何排序接口的beanFactory后置处理器
        // Finally, invoke all other BeanFactoryPostProcessors.
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
        for (String postProcessorName : nonOrderedPostProcessorNames) {
            nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

        /**********************第二步: 调用BeanFactoryPostProcessor Bean工厂的后置处理器  end****************************/
        // Clear cached merged bean definitions since the post-processors might have
        // modified the original metadata, e.g. replacing placeholders in values...
        beanFactory.clearMetadataCache();
    }
beanDefinitionRegistryPostProcessor-init.png
beanDefinitionRegistryPostProcessor-init.png

来看看源码是如何定义的. 重点看代码的注释, 每一部分的功能都有明确标出, 注释写的很详细

public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

        /**
         * 首先,调用BeanDefinitionRegistryPostProcessors的后置处理器
         * 定义已处理的后置处理器
         */
        // Invoke BeanDefinitionRegistryPostProcessors first, if any.
        Set<String> processedBeans = new HashSet<>();

        /**
         * 这里一共分为两大步:
         * 第一步: 调用所有实现了 BeanDefinitionRegistryPostProcessor 接口的bean定义. (BeanDefinitionRegistryPostProcessor带注册功能的后置处理器)
         * 第二步: 调用BeanFactoryPostProcessor Bean工厂的后置处理器
         */

        /**********************第一步: 调用所有实现了BeanDefinitionRegistryPostProcessor接口的bean定义  begin****************************/
        // 判断beanFactory是否实现了BeanDefinitionRegistry, 实现了该结构就有注册和获取Bean定义的能力
        if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    registryProcessors.add(registryProcessor);
                }
                else {
                    regularPostProcessors.add(postProcessor);
                }
            }

            // Do not initialize FactoryBeans here: We need to leave all regular beans
            // uninitialized to let the bean factory post-processors apply to them!
            // Separate between BeanDefinitionRegistryPostProcessors that implement
            // PriorityOrdered, Ordered, and the rest.
            /**
             * 这是一个集合, 存马上即将要被调用的BeanDefinitionRegistryPostProcessor
             */
            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
            // 第一步, 调用实现了PriorityOrdered的BeanDefinitionRegistryPostProcessors
            // 在所有创世纪的后置处理器中, 只有 internalConfigurationAnnotationProcessor 实现了 BeanDefinitionRegistryPostProcessors 和 PriorityOrdered
            // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 判断beanFactory是否实现了PriorityOrdered接口. 如果实现了,是最优先调用.
                // 在整个加载过程中,会调用四次BeanDefinitionRegistryPostProcessor, 而实现了PriorityOrdered的接口最先调用
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    // 调用beanFactory.getBean实例化创世界的类ppName
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            /**
             * 第一次调用BeanDefinitionRegistryPostProcessors
             * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor
             * 用于进行bean定义的加载 比如我们的包扫描 @import 等
             */
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // 处理完了,清空currentRegistryProcessors
            currentRegistryProcessors.clear();


            // 第二步: 调用实现 Ordered 的 BeanDefinitionRegistryPostProcessors。
            // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 这时实现了PriorityOrdered.class的postProcessor就不会再被加载进来了, 因为processedBeans.contains(ppName) == true
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    // 将其放入到currentRegistryProcessors, 马上就要被调用
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }

            // 对所有的处理器进行排序. 调用了Ordered的方法, 会返回排序(一个数字), 然后根据数字排序即可
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);

            /**
             * 第二次调用BeanDefinitionRegistryPostProcessors
             * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor
             * 用于进行bean定义的加载 比如我们的包扫描 @import 等
             */
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();


            // 第三步. 调用没有实现任何优先级接口的 BeanDefinitionRegistryPostProcessor
            // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
            boolean reiterate = true;
            while (reiterate) {
                reiterate = false;
                // 获取
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    // 已处理过的postProcessor不再处理
                    if (!processedBeans.contains(ppName)) {
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                        reiterate = true;
                    }
                }
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                /**
                 * 第三次调用BeanDefinitionRegistryPostProcessors
                 * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor
                 * 用于进行bean定义的加载 比如我们的包扫描 @import 等
                 */
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();
            }

            // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
            /*
             * 调用bean工厂的后置处理器
             * registryProcessors: 带有注册功能的bean工厂的后置处理器
             * regularPostProcessors: 不带注册功能的bean工厂的后置处理器
             */
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        }

        else {
            /*
             * 如果当前的beanFactory没有实现BeanDefinitionRegistry 说明没有注册Bean定义的能力
             * 那么就直接调用 BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法
             */

            // Invoke factory processors registered with the context instance.
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }

        /**********************第一步: 调用所有实现了BeanDefinitionRegistryPostProcessor接口的bean定义  end****************************/

        /**********************第二步: 调用BeanFactoryPostProcessor Bean工厂的后置处理器  begin****************************/

        // Do not initialize FactoryBeans here: We need to leave all regular beans
        // uninitialized to let the bean factory post-processors apply to them!
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

        // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
        // Ordered, and the rest.
        // 优先排序的后置处理器
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        List<String> orderedPostProcessorNames = new ArrayList<>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        for (String ppName : postProcessorNames) {
            if (processedBeans.contains(ppName)) {
                // skip - already processed in first phase above
            }
            else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            }
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            }
            else {
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        // 首先, 调用有优先级排序的后置处理器
        // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        // 第二, 调用实现了Ordered排序的后置处理器
        // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
        for (String postProcessorName : orderedPostProcessorNames) {
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

        // 最后, 调用没有实现任何排序接口的beanFactory后置处理器
        // Finally, invoke all other BeanFactoryPostProcessors.
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
        for (String postProcessorName : nonOrderedPostProcessorNames) {
            nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

        /**********************第二步: 调用BeanFactoryPostProcessor Bean工厂的后置处理器  end****************************/
        // Clear cached merged bean definitions since the post-processors might have
        // modified the original metadata, e.g. replacing placeholders in values...
        beanFactory.clearMetadataCache();
    }
beanDefinitionRegistryPostProcessor-init.png
beanDefinitionRegistryPostProcessor-init.png

下面我们就来分析上图所示的内容.

1. 对照源码和上图, 我们来看第一次调用

// 第一次, 调用实现了PriorityOrdered的BeanDefinitionRegistryPostProcessors
            // 在所有创世纪的后置处理器中, 只有 internalConfigurationAnnotationProcessor 实现了 BeanDefinitionRegistryPostProcessors 和 PriorityOrdered
            // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 判断beanFactory是否实现了PriorityOrdered接口. 如果实现了,是最优先调用.
                // 在整个加载过程中,会调用四次BeanDefinitionRegistryPostProcessor, 而实现了PriorityOrdered的接口最先调用
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    // 调用beanFactory.getBean实例化创世界的类ppName
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            /**
             * 第一次调用BeanDefinitionRegistryPostProcessors
             * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor
             * 用于进行bean定义的加载 比如我们的包扫描 @import 等
             */
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // 处理完了,清空currentRegistryProcessors
            currentRegistryProcessors.clear();

首先, 拿到了所有实现了BeanDefinitionRegistryPostProcessor的后置处理器, 上面我们做过铺垫,只有ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor后置处理器

所以,这里过滤出来的postProcessorNames只有一个值, 接下来, 判断, 这个类是否实现了PriorityOrdered 优先排序的接口, 如果实现了, 那么放入到currentRegistryProcessors中, 后面会进行调用.

接下来, 执行invokeBeanDefinitionRegistryPostProcessors

这是第一次调用BeanDefinitionRegistryPostProcessors

第二次调用BeanDefinitionRegistryPostProcessors

// 第二步: 调用实现 Ordered 的 BeanDefinitionRegistryPostProcessors。
            // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 这时实现了PriorityOrdered.class的postProcessor就不会再被加载进来了, 因为processedBeans.contains(ppName) == true
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    // 将其放入到currentRegistryProcessors, 马上就要被调用
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }

            // 对所有的处理器进行排序. 调用了Ordered的方法, 会返回排序(一个数字), 然后根据数字排序即可
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);

            /**
             * 第二次调用BeanDefinitionRegistryPostProcessors
             * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor
             * 用于进行bean定义的加载 比如我们的包扫描 @import 等
             */
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();

第二次调用的时候 ,依然是获取所有的实现了BeanDefinitionRegistryPostProcessor接口的后置处理器, 且这个处理器没有实现过PriorityOrdered也就是没有被上面调用过. 且实现了Ordered接口

这一类添加到currentRegistryProcessors集合中, 然后调用invokeBeanDefinitionRegistryPostProcessors处理

这是第二次调用BeanDefinitionRegistryPostProcessor

3. 第三次调用BeanDefinitionRegistryPostProcessor

// 第三步. 调用没有实现任何优先级接口的 BeanDefinitionRegistryPostProcessor
            // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
            boolean reiterate = true;
            while (reiterate) {
                reiterate = false;
                // 获取
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    // 已处理过的postProcessor不再处理
                    if (!processedBeans.contains(ppName)) {
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                        reiterate = true;
                    }
                }
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                /**
                 * 第三次调用BeanDefinitionRegistryPostProcessors
                 * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor
                 * 用于进行bean定义的加载 比如我们的包扫描 @import 等
                 */
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();
            }

第三次调用的是没有实现过任何排序接口的后置处理器. 并将其放入到currentRegistryProcessors, 然后执行invokeBeanDefinitionRegistryPostProcessors

4. 第四次调用

// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
/*
 * 调用bean工厂的后置处理器
 * registryProcessors: 带有注册功能的bean工厂的后置处理器
 * regularPostProcessors: 不带注册功能的bean工厂的后置处理器
 */
// 调用BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法----为什么是调用BeanDefinitionRegistryPostProcessor? 因为
// ConfigurationClassPostProcessor 实现了 BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessors
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
// 调用BeanFactoryPostProcessor 自设的(ConfigurationClassPostProcessor没有)
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

ConfigurationClassPostProcessor同时实现了BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessors, 调用的是

一共进行了4次调用

总结: 优先处理的是实现了PriorityOrdered的后置处理器, 然后调用实现了Order接口的后置处理器, 最后调用了没有实现任何排序方法的后置处理器. 最后调用工厂类方法.

下面我们来具体分析invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);

5. 提问: 检验一下是否理解了上面四个步骤

1. ConfigurationClassPostProcessor会调用1234哪几步?

因为ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor,PriorityOrdered, 因此会调用1,4

2. 如果自己定义了一个MyBeanFactoryPostProcessor会调用1234那几步?

package com.lxl.www.iocbeanlifecicle;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.stereotype.Component;

@Component
public class MyBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor {
   @Override
   public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {

   }

   @Override
   public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

   }
}
因为MyBeanFactoryPostProcessor是自定义的, 没有实现任何PriorityOrdered 或者 Order, 因此, 会调用3,4

6. 详细研究第四步, invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);的逻辑.

我们在这一步打个断点, 然后跟着断点一步一步点击进去

invokeBeanFactoryPostProcessors.png
invokeBeanFactoryPostProcessors.png
registryProcessors.png
registryProcessors.png

这是registryProcessors里面只有一个后置处理器, 就是ConfigurationClassPostProcessor.

然后进入到ConfigurationClassPostProcessor.postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)方法

@Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        int factoryId = System.identityHashCode(beanFactory);
        if (this.factoriesPostProcessed.contains(factoryId)) {
            throw new IllegalStateException(
                    "postProcessBeanFactory already called on this post-processor against " + beanFactory);
        }
        this.factoriesPostProcessed.add(factoryId);
        if (!this.registriesPostProcessed.contains(factoryId)) {
            // BeanDefinitionRegistryPostProcessor hook apparently not supported...
            // Simply call processConfigurationClasses lazily at this point then.
            processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
        }

        // 使用 cglib 配置类进行代理, 因为@Bean方法到时候要进行创建Bean的实例.
        enhanceConfigurationClasses(beanFactory);
        beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
    }

这里先看enhanceConfigurationClasses(beanFactory);个方法

public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
        Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();

        for (String beanName : beanFactory.getBeanDefinitionNames()) {
            BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
            Object configClassAttr = beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE);
            MethodMetadata methodMetadata = null;
            if (beanDef instanceof AnnotatedBeanDefinition) {
                methodMetadata = ((AnnotatedBeanDefinition) beanDef).getFactoryMethodMetadata();
            }
            if ((configClassAttr != null || methodMetadata != null) && beanDef instanceof AbstractBeanDefinition) {
                // Configuration class (full or lite) or a configuration-derived @Bean method
                // -> resolve bean class at this point...
                AbstractBeanDefinition abd = (AbstractBeanDefinition) beanDef;
                if (!abd.hasBeanClass()) {
                    try {
                        abd.resolveBeanClass(this.beanClassLoader);
                    }
                    catch (Throwable ex) {
                        throw new IllegalStateException(
                                "Cannot load configuration class: " + beanDef.getBeanClassName(), ex);
                    }
                }
            }

            /**
             * 只有full版配置才会创建cglib代理
             * full是怎么来的呢? 我们使用@Configuration注解了, 在加载的时候, 就会设置为full
             * 当设置为full以后, 我们在调用的时候, 就会创建一个cglib动态代理.
             *
             * 为什么要创建动态代理呢?
             * 动态代理可以保证, 每次创建的bean对象只有一个
             *
             * 那么加@Configuration和不加本质上的区别是什么?
             * 当在配置类中一个@Bean使用方法的方式引入另一个Bean的时候, 如果不加@Configuration注解, 就会重复加载Bean
             * 如果加了@Configuration, 则会在这里创建一个cglib代理, 当调用了@Bean方法是会先检测容器中是否存在这个Bean, 如果不存在则创建, 存在则直接使用.
             */
            if (ConfigurationClassUtils.CONFIGURATION_CLASS_FULL.equals(configClassAttr)) {
                if (!(beanDef instanceof AbstractBeanDefinition)) {
                    throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" +
                            beanName + "' since it is not stored in an AbstractBeanDefinition subclass");
                }
                else if (logger.isInfoEnabled() && beanFactory.containsSingleton(beanName)) {
                    logger.info("Cannot enhance @Configuration bean definition '" + beanName +
                            "' since its singleton instance has been created too early. The typical cause " +
                            "is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " +
                            "return type: Consider declaring such methods as 'static'.");
                }
                configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
            }
        }
        if (configBeanDefs.isEmpty()) {
            // nothing to enhance -> return immediately
            return;
        }

        ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
        for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
            AbstractBeanDefinition beanDef = entry.getValue();
            // If a @Configuration class gets proxied, always proxy the target class
            beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
            // Set enhanced subclass of the user-specified bean class
            Class<?> configClass = beanDef.getBeanClass();
            Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
            if (configClass != enhancedClass) {
                if (logger.isTraceEnabled()) {
                    logger.trace(String.format("Replacing bean definition '%s' existing class '%s' with " +
                            "enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));
                }
                beanDef.setBeanClass(enhancedClass);
            }
        }
    }

粗体部分就是判断是否需要进行cglib代理. 进行cglib代理的条件是, beanDefinition中属性configurationClass的值是full. 只有full版配置才会创建cglib代理

那么有下面几个问题:

问题1: full版本配置是什么呢?

我们使用@Configuration注解了, 在加载的时候, 就会将configurationClass属性设置为full.当设置为full以后, 我们在调用的时候, 就会创建一个cglib动态代理.

问题2: 为什么要创建动态代理呢?

动态代理可以保证, 每次创建的bean对象只有一个

问题3:那么加@Configuration和不加本质上的区别是什么?

当在配置类中一个@Bean使用方法的方式引入另一个Bean的时候, 如果不加@Configuration注解, 就会重复加载Bean.如果加了@Configuration, 则会在这里创建一个cglib代理, 当调用了@Bean方法是会先检测容器中是否存在这个Bean, 如果不存在则创建, 存在则直接使用.

问题4:full是怎么来的呢?
这是在上面调用invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);接口的时候, 标记的是full还是Lite

下面来看一下源码

postProcessorRegistrationDelegate.png
postProcessorRegistrationDelegate.png

在这里一步,执行的时候,进行了这个类是full的还是lite,继续忘下看

invokeBeanDefinitionRegistryPostProcessors-detail.png
invokeBeanDefinitionRegistryPostProcessors-detail.png

此时满足条件的postProcessor只有一个, 那就是ConfigurationClassPostProcessor. 下面直接看ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry()方法

postProcessBeanDefinitionRegistry-detail.png
postProcessBeanDefinitionRegistry-detail.png

前面都是一些条件判断, 重点看processConfigBeanDefinitions(registry);

processConfigBeanDefinitions-detail.png
processConfigBeanDefinitions-detail.png

在这里,这个方法判断了, 这个类是full的还是lite的. 下面直接上代码

/**
     * Check whether the given bean definition is a candidate for a configuration class
     * (or a nested component class declared within a configuration/component class,
     * to be auto-registered as well), and mark it accordingly.
     * @param beanDef the bean definition to check
     * @param metadataReaderFactory the current factory in use by the caller
     * @return whether the candidate qualifies as (any kind of) configuration class
     */
    public static boolean checkConfigurationClassCandidate(
            BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {

        String className = beanDef.getBeanClassName();
        if (className == null || beanDef.getFactoryMethodName() != null) {
            return false;
        }

        AnnotationMetadata metadata;
        // 获取元数据
        if (beanDef instanceof AnnotatedBeanDefinition &&
                className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) {
            // Can reuse the pre-parsed metadata from the given BeanDefinition...
            metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata();
        }
        else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
            // Check already loaded Class if present...
            // since we possibly can't even load the class file for this Class.
            Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
            if (BeanFactoryPostProcessor.class.isAssignableFrom(beanClass) ||
                    BeanPostProcessor.class.isAssignableFrom(beanClass) ||
                    AopInfrastructureBean.class.isAssignableFrom(beanClass) ||
                    EventListenerFactory.class.isAssignableFrom(beanClass)) {
                return false;
            }
            metadata = AnnotationMetadata.introspect(beanClass);
        }
        else {
            try {
                MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
                metadata = metadataReader.getAnnotationMetadata();
            }
            catch (IOException ex) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Could not find class file for introspecting configuration annotations: " +
                            className, ex);
                }
                return false;
            }
        }

        // 判断元数据中是否包含Configuration注解
        Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
        /**
         * 判断, proxyBeanMethods属性是否为true, 如果为true就是一个完全的类,
         * 也就是带有@Configuration注解, 设置Configuration_class属性为full
         *
         * proxyBeanMethods配置类是用来指定@Bean注解标注的方法是否使用代理,
         * 默认是true使用代理,直接从IOC容器之中取得对象;
         * 如果设置为false,也就是不使用注解,每次调用@Bean标注的方法获取到的对象和IOC容器中的都不一样,是一个新的对象,所以我们可以将此属性设置为false来提高性能。
         */
        if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
            beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
        }
        // 判断是不是带了@Component, @ComponentScan @Import @ImportResource @Bean注解,
        // 如果带有这几种注解, 就将其Configuration_class属性为lite类型的配置类
        else if (config != null || isConfigurationCandidate(metadata)) {
            beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
        }
        else {
            return false;
        }

        // It's a full or lite configuration candidate... Let's determine the order value, if any.
        Integer order = getOrder(metadata);
        if (order != null) {
            beanDef.setAttribute(ORDER_ATTRIBUTE, order);
        }

        return true;
    }

上面主要是获取元数据, 然后判断元数据中是否有Configuration注解. 如果有,返回其属性. 我们判断其属性中proxyBeanMethods是否true, 如果是true, 那么将其设置为full.

如果配置中带有@Component, @ComponentScan @Import @ImportResource @Bean这几种属性之一, 那么就将其设置为lite.
问题5: cglib动态代理做了什么事情呢? 不看源码的情况下, 简单可以理解为, 去ioc工厂里面通过getBean(“car”) 查询了看ioc中是否有这个对象, 如果有就取出来, 不再另创建.
这也是@Configuration 和其他注解类似@Component和@ComponentScan的本质区别:

当在配置类中一个@Bean使用方法的方式引入另一个Bean的时候, 如果不加@Configuration注解, 就会重复加载Bean

如果加了@Configuration, 则会在这里创建一个cglib代理, 当调用了@Bean方法是会先检测容器中是否存在这个Bean, 如果不存在则创建, 存在则直接使用.

下面来看个例子

基础类:
public class Car  {
    private String name;
    private Tank tank;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Tank getTank() {
        return tank;
    }

    public void setTank(Tank tank) {
        this.tank = tank;
    }
}

public class Tank {
    private String name;

    public Tank() {
        System.out.println("创建一个tank");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

这是定义的car和tank的基础类

@Configuration
@ComponentScan(basePackages = {"com.lxl.www.iocbeanlifecicle"})
public class MainConfig {

    @Bean("car")
    public Car car() {
        Car car = new Car();
        car.setName("zhangsan");
        // 这里调用了Tank类, tank是通过@Bean注解注入的. 
        car.setTank(tank());
        return car;
    }

    @Bean
    public Tank tank() {
        return new Tank();
    }
}

当配置类使用了@Configuration注解的时候, 运行main方法

public class MainStarter {
    public static void main(String[] args) {
        // 第一步: 通过AnnotationConfigApplicationContext读取一个配置类
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
        context.scan("package");
        //context.addBeanFactoryPostProcessor();
        Car car = (Car) context.getBean("car");
        Car car2 = (Car) context.getBean("car");
        System.out.println(car.getName());
        context.close();
    }
}
spring5-postprocess-source-code-analysis-main-task.png
spring5-postprocess-source-code-analysis-main-task.png

当去掉@Configuration注解的时候, 再次运行, 我们看到创建了两次tank

//@Configuration
@ComponentScan(basePackages = {"com.lxl.www.iocbeanlifecicle"})
public class MainConfig {

    @Bean("car")
    public Car car() {
        Car car = new Car();
        car.setName("zhangsan");
        // 这里调用了Tank类, tank是通过@Bean注解注入的. 
        car.setTank(tank());
        return car;
    }

    @Bean
    public Tank tank() {
        return new Tank();
    }
}
analysis-task-rank-detail.png
analysis-task-rank-detail.png

在main方法中调用了两次(Car) context.getBean(“car”);

在new一个对象的时候, 如果不取ioc容器中取, 那么每一次都会创建一个新的.

在ioc容器中, car对象只有一个, 但是在构建car的时候, 调用了tank, tank在ioc容器中却不一定只有一份. 只有使用了@Configuration, 表示需要使用cglib动态代理查找tank类, 保证ioc容器中只有一份.

以上详细研究了配置类加载的过程, 以及配置类中设置@Configuration和@Component的区别.

后面还会继续分析,加载@ComponentScan的时候, 都做了哪些事.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK