spring5源码系列---内置的后置处理器PostProcess加载源码

准备工作: 自定义配置类MainConfig
我们先定义好要分析加载的配置类

复制代码
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指定当前是一个配置类

接下来定义一个main方法, 加载配置类.
复制代码
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.

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

始终不要忘记我们的整体架构图. 对照这个图来分析. 思路更清晰. 整体内容讲解在这里: https://www.cnblogs.com/ITPower/p/13677635.html

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

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 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个原始RootBeanDefinition, 这些bean是spring自己提前定义好的, 他们的加载是整个spring的基础. 用于解析spring中其他的类

而这一次我们要研究配置类是如何被读取的, 所以重点关注的是下面这个后置处理器

ConfigurationClassPostProcessor.class

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

3.2 ConfigurationClassPostProcessor的继承结构

可以看到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);

// 这里,如果已经存在,说明被重复加载了, 那么后面加载的会覆盖前面加载的bean
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 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是处理循环引用的问题, 暂时先不要看.

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

3.4 初始化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

备注:

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

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

四. 读取自定义配置类MainConfig
注册配置类,入口自然是这里了

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

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

复制代码
private void doRegisterBean(Class beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier 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中

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

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

到这里,我们完成了两步.

第一步: 准备工具类ConfigurationClassPostProcessor

第二步: 准备配置类MainConfig.

接下俩, 就是要使用工具类来解析配置类MainConfig了

五. 调用bean工厂的后置处理器invokeBeanFactoryPostProcessors(beanFactory);
复制代码
public AnnotationConfigApplicationContext(Class<?>… componentClasses) {
// 进入构造函数, 首先调用自身的构造方法this();
// 调用自身的构造方法之前, 要先调用父类的构造方法
this();
// register配置注册类
register(componentClasses);
// ioc容器刷新接口–非常重要
refresh();
}
复制代码
在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 getBeanFactoryPostProcessors() {
return this.beanFactoryPostProcessors;
}
getBeanFactoryPostProcessors() 返回的是一个工厂的后置处理器的List, 这个时候list是空的
getBeanFactoryPostProcessors()里面的值是怎么来的呢?
通过在自定义main方法中调用context.addBeanFactoryPostProcessor(…);来添加. 也就是通过main方法手动添加的beanFactoryPostProcessor. 如下所示
复制代码
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 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();
}

复制代码

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

  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只有一个,就是ConfigurationClassPostProcessor, 接下来, 判断这个类是否实现了PriorityOrdered 优先排序的接口, 如果实现了, 那么放入到currentRegistryProcessors中, 后面会进行调用.

接下来, 执行invokeBeanDefinitionRegistryPostProcessors

这是第一次调用BeanDefinitionRegistryPostProcessors

  1. 第二次调用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

  1. 第三次调用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

  1. 第四次调用
    复制代码
    // 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, 调用的是invokeBeanFactoryPostProcessors

一共进行了4次调用

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

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

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

复制代码

  1. ConfigurationClassPostProcessor会调用1234哪几步?

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

  1. 如果自己定义了一个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
复制代码

二. 详细研究第四步, invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);的逻辑.
我们在这一步打个断点, 然后跟着断点一步一步点击进去

这是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

下面来看一下源码

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

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

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

在这里,这个方法判断了, 这个类是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();
}
}
复制代码

当去掉@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();
}

}
复制代码

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

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

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

  1. 详细研究四次调用中的第一次调用. 通过分析跟踪@ComponentScan注解是如何解析的,
    通过跟踪@ComponentScan注解是如何解析的, 分来理解BeanDefinitionScan, BeanDefinitionRegistry, BeanDefinitionReader是如何工作的.

复制代码
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List 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();

复制代码
亚马逊测评 www.yisuping.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值