Spring5IOC容器解析——注解配置的资源定位、加载、解析、注册分析

AnnotationConfigApplicationContext

使用AnnotationConfigApplicationContext可以实现基于Java的配置类(包括各种注解)加载Spring的应用上下文。避免使用application.xml进行配置。相比XML配置,更加便捷。

一、被@Configuration标记的Bean的资源定位、加载、解析、注册分析

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Xxx.class);
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {

    //保存一个读取注解的Bean 定义读取器,并将其设置到容器中
    private final AnnotatedBeanDefinitionReader reader;
    //保存一个扫描指定类路径中注解Bean 定义的扫描器,并将其设置到容器中
    private final ClassPathBeanDefinitionScanner scanner;
    
    /**
     * 默认构造函数,初始化一个空容器,容器不包含任何Bean 信息,需要在稍后通过调用其register()
     * 方法注册配置类,并调用refresh()方法刷新容器,触发容器对注解Bean 的载入、解析和注册过程
     * Create a new AnnotationConfigApplicationContext that needs to be populated
     * through {@link #register} calls and then manually {@linkplain #refresh refreshed}.
     */
    public AnnotationConfigApplicationContext() {
        this.reader = new AnnotatedBeanDefinitionReader(this);
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }   
    
    public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
        //调用默认无参构造器,主要初始化AnnotatedBeanDefinitionReader
        // 以及路径扫描器ClassPathBeanDefinitionScanner
        this();
        //把传入的Class进行注册,Class既可以有@Configuration注解,也可以没有@Configuration注解
        //如何注册委托给了 org.springframework.context.annotation.AnnotatedBeanDefinitionReader.register 方法进行注册
        // 包装传入的Class 生成 BeanDefinition , 注册到BeanDefinitionRegistry
        register(componentClasses);
        refresh();
    }

    @Override
    public void register(Class<?>... componentClasses) {
        Assert.notEmpty(componentClasses, "At least one component class must be specified");
        this.reader.register(componentClasses);
    }
}

AnnotatedBeanDefinitionReader

发现 AnnotatedBeanDefinitionReader没有继承和实现任何类与接口,即该类并不属于BeanDefinitionReader的体系,而是专门用于处理注解相关的BeanDefinition的配置读入,这样做可以用于区分出注解和其他配置方式的不同。
注解的处理逻辑相对更清晰,在上一文分析了XML相关的解析逻辑之后,理解注解也会相对容易一些。

深入this.reader.register(componentClasses)方法,进入AnnotatedBeanDefinitionReader类

public class AnnotatedBeanDefinitionReader {

    //还是委托BeanDefinitionRegistry将AnnotatedBeanDefinition实例注入到IOC容器中
    private final BeanDefinitionRegistry registry;

    public void register(Class<?>... componentClasses) {
        for (Class<?> componentClass : componentClasses) {
            registerBean(componentClass);
        }
    }

    public void registerBean(Class<?> beanClass) {
        doRegisterBean(beanClass, null, null, null, null);
    }
}

doRegisterBean()方法真正的注册方法,继续深入

public class AnnotatedBeanDefinitionReader {

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

        AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
        //此段代码用于处理 Conditional 注解,在特定条件下阻断 bean 的注册
        if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
            return;
        }
        //用来创建 bean 的 supplier,会替代掉 bean 本身的创建方法
        //instanceSupplier 一般情况下为 null
        abd.setInstanceSupplier(supplier);
        //此行代码处理 scope 注解,本例中 scope 是默认值 singleton
        ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
        abd.setScope(scopeMetadata.getScopeName());
        //获取beanName
        String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

        //特定注解解析,本例中均没传入dependsOn,LazyInit这些注解
        //这些注解就和<bean>标签里面的属性作用是一样的
        AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
        //本例中 qualifiers 传入的是 null,qualifiers就是用来决定接口的实现类的
        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));
                }
            }
        }
        //主要提供对BeanDefinition的一些定制化操作
        if (customizers != null) {
            for (BeanDefinitionCustomizer customizer : customizers) {
                customizer.customize(abd);
            }
        }
        //用 BeanDefinitionHolder 包装 BeanDefinition
        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
        //此行代码与动态代理和 scope 注解有关,主要看看是否依照Spring的scope生成动态代理对象
        // 但是在本案例中没有做任何操作,只是返回了传入的 definitionHolder
        definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
        //向容器注册扫描到的Bean
        BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
    }
}
  • 1、将类转换为AnnotatedGenericBeanDefinition。
  • 2、调用conditionEvaluator的shouldSkip判断是否需要过滤,shouldSkip方法中先判断类上是否有Conditional注解,只处理有Conditional注解或其衍生注解的情况。
  • 3、获取beanName,如果我们设置了value则取其值,如果没有设置,底层上是调用JDK的Introspector.decapitalize方法,比如类名是HelloWorld,则对应的beanName是helloWorld。
  • 4、调用AnnotationConfigUtils.processCommonDefinitionAnnotations,获取Lazy、Primary、DependsOn等注解的值。
  • 5、最后调用BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry)将这个BeanDefinition注册到registry中,这里的注册和xml方式的注册一模一样。

使用AnnotationConfigUtils的processCommonDefinitionAnnotations方法处理注解Bean定义类中通用的注解

二、不是被@Configuration标记的Bean(即普通的业务Bean)的资源定位、加载、解析、注册分析

public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {

    public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
        //调用默认无参构造器,主要初始化AnnotatedBeanDefinitionReader
        // 以及路径扫描器ClassPathBeanDefinitionScanner
        this();
        //把传入的Class进行注册,Class既可以有@Configuration注解,也可以没有@Configuration注解
        //如何注册委托给了 org.springframework.context.annotation.AnnotatedBeanDefinitionReader.register 方法进行注册
        // 包装传入的Class 生成 BeanDefinition , 注册到BeanDefinitionRegistry
        register(componentClasses);

        //@Controller、@Service、@Component、@Repository标记的类在此方法被注册进IOC容器
        refresh();
    }
}

针对普通的业务Bean,即@Controller、@Service、@Component、@Repository标记的类是在AnnotationConfigApplicationContext构造函数中的refresh()方法的时候才会被注册进IOC容器,这和XML解析方式一样是调用的AbstractApplicationContext中的refresh()方法。

  • XML配置方式的解析配置并注册BeanDefinition实例时候,是调用的obtainFreshBeanFactory()方法。
  • 而注解方式是调用的invokeBeanFactoryPostProcessors(beanFactory)方法,在容器调用其后置处理器的时候会触发对普通的BeanDefinition的注册。
public abstract class AbstractApplicationContext extends DefaultResourceLoader
        implements ConfigurableApplicationContext {

    /**
     * 加载或刷新一个持久化的配置,可能是XML文件、属性文件或关系数据库模式。
     * 由于这是一种启动方法,如果失败,应该销毁已经创建的单例,以避免悬空资源。
     * 换句话说,在调用该方法之后,要么全部实例化,要么完全不实例化。
     * @throws BeansException 如果bean工厂无法初始化,则抛出 BeansException 异常
     * @throws IllegalStateException 如果已经初始化且不支持多次刷新,则会抛出 IllegalStateException 异常
     */
    @Override
    public void refresh() throws BeansException, IllegalStateException {
        // 给容器refresh加锁,避免容器处在refresh阶段时,容器进行了初始化或者销毁的操作
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            // 调用容器准备刷新的方法,获取容器的当时时间,同时给容器设置同步标识,具体方法
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            //告诉子类启动refreshBeanFactory()方法,Bean定义资源文件的载入从
            //子类的refreshBeanFactory()方法启动,里面有抽象方法
            //针对xml配置,最终创建内部容器,该容器负责 Bean 的创建与管理,此步会进行BeanDefinition的注册
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            // 注册一些容器中需要的系统Bean.例如classloader,beanfactoryPostProcessor等
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                //允许容器的子类去注册postProcessor  ,钩子方法
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                // 激活在容器中注册为bean的BeanFactoryPostProcessors
                //对于注解容器,org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
                //方法扫描应用中所有BeanDefinition并注册到容器之中
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                // 注册拦截bean创建过程的BeanPostProcessor
                registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                // 找到“messageSource”的Bean提供给ApplicationContext使用,
                // 使得ApplicationContext具有国际化能力。
                initMessageSource();

                // Initialize event multicaster for this context.
                // 初始化ApplicationEventMulticaster该类作为事件发布者,
                // 可以存储所有事件监听者信息,并根据不同的事件,通知不同的事件监听者。
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                // 预留给 AbstractApplicationContext 的子类用于初始化其他特殊的 bean,
                // 该方法需要在所有单例 bean 初始化之前调用
                // 比如Web容器就会去初始化一些和主题展示相关的Bean(ThemeSource)
                onRefresh();

                // Check for listener beans and register them.
                // 注册监听器(检查监听器的bean并注册它们)
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                //设置自定义的类型转化器ConversionService,
                // 设置自定义AOP相关的类LoadTimeWeaverAware,
                // 清除临时的ClassLoader
                // ,实例化所有的类(懒加载的类除外)
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                // 初始化容器的生命周期事件处理器,(默认使用DefaultLifecycleProcessor),调用扩展了SmartLifecycle接口的start方法
                // 当Spring容器加载所有bean并完成初始化之后,会接着回调实现该接口的类中对应的方法(start()方法)
                // 并发布容器刷新完毕事件ContextRefreshedEvent给对应的事件监听者
                finishRefresh();
            }

            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }

                // Destroy already created singletons to avoid dangling resources.
                //销毁已创建的Bean
                destroyBeans();

                // Reset 'active' flag.
                //取消refresh操作,重置容器的同步标识
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }

            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                // 重置Spring内核中的共用的缓存,因为我们可能再也不需要单例bean的元数据了……
                resetCommonCaches();
            }
        }
    }
}

invokeBeanFactoryPostProcessors(beanFactory)方法中

  • 该方法会实例化和调用所有 BeanFactoryPostProcessor(包括其子类 BeanDefinitionRegistryPostProcessor)。
  • BeanFactoryPostProcessor 接口是 Spring 初始化 BeanFactory 时对外暴露的扩展点,Spring IoC 容器允许 BeanFactoryPostProcessor 在容器实例化任何 bean 之前读取 bean 的定义,并可以修改它。
  • BeanDefinitionRegistryPostProcessor 继承自 BeanFactoryPostProcessor,比 BeanFactoryPostProcessor 具有更高的优先级,主要用来在常规的 BeanFactoryPostProcessor 检测开始之前注册其他 bean 定义。特别是,你可以通过 BeanDefinitionRegistryPostProcessor 来注册一些常规的 BeanFactoryPostProcessor,因为此时所有常规的 BeanFactoryPostProcessor 都还没开始被处理。

注:这边的 “常规 BeanFactoryPostProcessor” 主要用来跟 BeanDefinitionRegistryPostProcessor 区分。

接着深入invokeBeanFactoryPostProcessors(beanFactory)方法

public abstract class AbstractApplicationContext extends DefaultResourceLoader
        implements ConfigurableApplicationContext {

    /**
     * 实例化并调用所有已注册的BeanFactoryPostProcessor 的 bean,如果已给出顺序,请按照顺序。
     * 必须在单实例实例化之前调用。
     * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
     * respecting explicit order if given.
     * <p>Must be called before singleton instantiation.
     */
    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        // 1.getBeanFactoryPostProcessors(): 拿到当前应用上下文beanFactoryPostProcessors变量中的值
        // 2.invokeBeanFactoryPostProcessors: 实例化并调用所有已注册的BeanFactoryPostProcessor
        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

        // 如何找到一个LoadTimeWeaver,那么就准备将后置处理器“织入”bean工厂
        // (例如,一个 @Bean 方法通过ConfigurationClassPostProcessor来注册)
        // 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()));
        }
    }
}

1、拿到当前应用上下文 beanFactoryPostProcessors 变量中的值。

public abstract class AbstractApplicationContext extends DefaultResourceLoader
        implements ConfigurableApplicationContext {

    //应用于刷新的 BeanFactoryPostProcessors,这个List用于存放Bean工厂处理器(BeanFactoryPostProcessor)
    private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();

    //返回将应用到内部BeanFactory的BeanFactoryPostProcessors列表
    public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
        return this.beanFactoryPostProcessors;
    }
}

这边 getBeanFactoryPostProcessors() 会拿到当前应用上下文中已经注册的 BeanFactoryPostProcessor,在默认情况下,this.beanFactoryPostProcessors 是返回空的。

如何添加自定义 BeanFactoryPostProcessor 到 this.beanFactoryPostProcessors 变量中?

新建一个 ApplicationContextInitializer 的实现类 SpringApplicationContextInitializer ,并在 initialize 方法中写我们的逻辑。

public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
 
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        FirstBeanDefinitionRegistryPostProcessor firstBeanDefinitionRegistryPostProcessor = new FirstBeanDefinitionRegistryPostProcessor();
        // 将自定义的firstBeanDefinitionRegistryPostProcessor添加到应用上下文中
        applicationContext.addBeanFactoryPostProcessor(firstBeanDefinitionRegistryPostProcessor);
        // ...自定义操作
        System.out.println("MyApplicationContextInitializer#initialize");
    }
}
1、Spring实现方式

将 SpringApplicationContextInitializer 作为初始化参数 contextInitializerClasses 配置到 web.xml 中。

<context-param>
    <param-name>contextInitializerClasses</param-name>
    <param-value>
        com.yibo.spring.MyApplicationContextInitializer
    </param-value>
</context-param>

这样,在启动应用时,FirstBeanDefinitionRegistryPostProcessor 就会被添加到 this.beanFactoryPostProcessors 中。

2、SpringBoot方式
2.1、mian函数中添加
@SpringBootApplication
public class MySpringBootApplication {
    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(MySpringBootApplication.class);
        application.addInitializers(new MyApplicationContextInitializer());
        application.run(args);
    }
}
2.2、配置文件中配置
context.initializer.classes= com.yibo.spring.MyApplicationContextInitializer
2.3、SpringBoot的SPI扩展---META-INF/spring.factories中配置

在项目下的resources下新建META-INF文件夹,文件夹下新建spring.factories文件

org.springframework.context.ApplicationContextInitializer= com.yibo.spring.MyApplicationContextInitializer

给 MyApplicationContextInitializer 加上Order注解:我们指定其拥有最高的排序级别。(越高越早执行)

@Order(Ordered.HIGHEST_PRECEDENCE)
public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
 
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        FirstBeanDefinitionRegistryPostProcessor firstBeanDefinitionRegistryPostProcessor = new FirstBeanDefinitionRegistryPostProcessor();
        // 将自定义的firstBeanDefinitionRegistryPostProcessor添加到应用上下文中
        applicationContext.addBeanFactoryPostProcessor(firstBeanDefinitionRegistryPostProcessor);
        // ...自定义操作
        System.out.println("MyApplicationContextInitializer#initialize");
    }
}

2、实例化并调用所有已注册的 BeanFactoryPostProcessor

深入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())

final class PostProcessorRegistrationDelegate {

    /**
     * 调用BeanFactoryPostProcessor
     * 主要是分情况处理不同类型的BeanFactoryPostProcessors。
     * BeanFacotryPostProcessors主要分为两类,一类是BeanDefinitionRegistry的BeanFactoryPostProcessor,另外一类是常规的BeanFactoryPostProcessor。
     * 优先处理前者。同时,这两种后置处理器又被分为从参数里传入和从容器里获取的,最终要将从参数里获取的和从容器里获取的合并在一起。
     * 合并的时候又分为实现了PriorityOrder和普通Order以及没有实现这两个接口的,实现了PriorityOrdered的先执行,
     * 同时是按照PriorityOrdered顺序执行的,其次再到Order,按照Order执行,最后才是没实现这两个接口的,
     * 先执行完BeanDefinitionRegistryPostProcessor的invokeBeanDefinitionRegistryPostProcessors方法,
     * 再对BeanDefinitionRegistryPostProcessor执行invokeBeanFactoryPostProcessors方法,
     * 之后再对常规的BeanFacotryPostProcessors执行invokeBeanFactoryPostProcessors方法
     * @参数 beanFactory 应用上下文的 BeanFactory 实例
     * @参数 beanFactoryPostProcessors 应用上下文指定要执行的 BeanFactoryPostProcessor
     **/
    public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

        // Invoke BeanDefinitionRegistryPostProcessors first, if any.
        // 如果有BeanDefinitionRegistryPostProcessor的话优先执行
        Set<String> processedBeans = new HashSet<>();

        // 1.判断beanFactory是否为BeanDefinitionRegistry,beanFactory为DefaultListableBeanFactory,
        // 而DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,因此这边为true
        if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            // 用于存放普通的BeanFactoryPostProcessor
            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
            // 用于存放BeanDefinitionRegistryPostProcessor
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

            // 2.首先处理入参中的beanFactoryPostProcessors
            // 遍历所有的beanFactoryPostProcessors, 将BeanDefinitionRegistryPostProcessor和普通BeanFactoryPostProcessor区分开
            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    // 2.1 如果是BeanDefinitionRegistryPostProcessor
                    BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
                    // 2.1.1 直接执行BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    // 2.1.2 添加到registryProcessors(用于最后执行postProcessBeanFactory方法)
                    registryProcessors.add(registryProcessor);
                }
                else {
                    // 2.2 否则,只是普通的BeanFactoryPostProcessor
                    // 2.2.1 添加到regularPostProcessors(用于最后执行postProcessBeanFactory方法)
                    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<>();

            // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
            // 3.调用所有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor实现类
            // 3.1 找出所有实现BeanDefinitionRegistryPostProcessor接口的Bean的beanName
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            // 3.2 遍历postProcessorNames
            for (String ppName : postProcessorNames) {
                // 3.3 校验是否实现了PriorityOrdered接口
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    // 3.4 获取ppName对应的bean实例, 添加到currentRegistryProcessors中,
                    // beanFactory.getBean: 这边getBean方法会触发创建ppName对应的bean对象, 目前暂不深入解析
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    // 3.5 将要被执行的加入processedBeans,避免后续重复执行
                    processedBeans.add(ppName);
                }
            }
            // 3.6 进行排序(根据是否实现PriorityOrdered、Ordered接口和order值来排序)
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            // 3.7 添加到registryProcessors(用于最后执行postProcessBeanFactory方法)
            registryProcessors.addAll(currentRegistryProcessors);
            // 3.8 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // 3.9 执行完毕后, 清空currentRegistryProcessors
            currentRegistryProcessors.clear();

            // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
            // 4.调用所有实现了Ordered接口的BeanDefinitionRegistryPostProcessor实现类(过程跟上面的步骤3基本一样)
            // 4.1 找出所有实现BeanDefinitionRegistryPostProcessor接口的类, 这边重复查找是因为执行完上面的BeanDefinitionRegistryPostProcessor,
            // 可能会新增了其他的BeanDefinitionRegistryPostProcessor, 因此需要重新查找
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 校验是否实现了Ordered接口,并且还未执行过
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            // 4.2 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();

            // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
            // 5.最后, 调用所有剩下的BeanDefinitionRegistryPostProcessors
            boolean reiterate = true;
            while (reiterate) {
                reiterate = false;
                // 5.1 找出所有实现BeanDefinitionRegistryPostProcessor接口的类
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    // 5.2 跳过已经执行过的
                    if (!processedBeans.contains(ppName)) {
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                        // 5.3 如果有BeanDefinitionRegistryPostProcessor被执行, 则有可能会产生新的BeanDefinitionRegistryPostProcessor,
                        // 因此这边将reiterate赋值为true, 代表需要再循环查找一次
                        reiterate = true;
                    }
                }
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                // 5.4 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();
            }

            // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
            // 6.调用所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法(BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProcessor)
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            // 7.最后, 调用入参beanFactoryPostProcessors中的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        }

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

        // Do not initialize FactoryBeans here: We need to leave all regular beans
        // uninitialized to let the bean factory post-processors apply to them!
        // 到这里 , 入参beanFactoryPostProcessors和容器中的所有BeanDefinitionRegistryPostProcessor已经全部处理完毕,
        // 下面开始处理容器中的所有BeanFactoryPostProcessor
        // 8.找出所有实现BeanFactoryPostProcessor接口的类
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

        // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
        // Ordered, and the rest.
        // 用于存放实现了PriorityOrdered接口的BeanFactoryPostProcessor
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        // 用于存放实现了Ordered接口的BeanFactoryPostProcessor的beanName
        List<String> orderedPostProcessorNames = new ArrayList<>();
        // 用于存放普通BeanFactoryPostProcessor的beanName
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        // 8.1 遍历postProcessorNames, 将BeanFactoryPostProcessor按实现PriorityOrdered、实现Ordered接口、普通三种区分开
        for (String ppName : postProcessorNames) {
            // 8.2 跳过已经执行过的
            if (processedBeans.contains(ppName)) {
                // skip - already processed in first phase above
            }
            else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                // 8.3 添加实现了PriorityOrdered接口的BeanFactoryPostProcessor
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            }
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                // 8.4 添加实现了Ordered接口的BeanFactoryPostProcessor的beanName
                orderedPostProcessorNames.add(ppName);
            }
            else {
                // 8.5 添加剩下的普通BeanFactoryPostProcessor的beanName
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
        // 9.调用所有实现PriorityOrdered接口的BeanFactoryPostProcessor
        // 9.1 对priorityOrderedPostProcessors排序
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        // 9.2 遍历priorityOrderedPostProcessors, 执行postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
        // 10.调用所有实现Ordered接口的BeanFactoryPostProcessor
        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
        for (String postProcessorName : orderedPostProcessorNames) {
            // 10.1 获取postProcessorName对应的bean实例, 添加到orderedPostProcessors, 准备执行
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        // 10.2 对orderedPostProcessors排序
        sortPostProcessors(orderedPostProcessors, beanFactory);
        // 10.3 遍历orderedPostProcessors, 执行postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

        // Finally, invoke all other BeanFactoryPostProcessors.
        // 11.调用所有剩下的BeanFactoryPostProcessor
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
        for (String postProcessorName : nonOrderedPostProcessorNames) {
            // 11.1 获取postProcessorName对应的bean实例, 添加到nonOrderedPostProcessors, 准备执行
            nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        // 11.2 遍历nonOrderedPostProcessors, 执行postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

        // Clear cached merged bean definitions since the post-processors might have
        // modified the original metadata, e.g. replacing placeholders in values...
        // 12.清除元数据缓存(mergedBeanDefinitions、allBeanNamesByType、singletonBeanNamesByType),
        // 因为后处理器可能已经修改了原始元数据,例如, 替换值中的占位符...
        beanFactory.clearMetadataCache();
    }
}

调用invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry)进行BeanDefinition的注册

private static void invokeBeanDefinitionRegistryPostProcessors(
        Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {

    for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
        postProcessor.postProcessBeanDefinitionRegistry(registry);
    }
}

上一步每一个BeanDefinitionRegistryPostProcessor都会调用postProcessBeanDefinitionRegistry(registry)进行处理,继续深入该方法

public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
        PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
        int registryId = System.identityHashCode(registry);
        if (this.registriesPostProcessed.contains(registryId)) {
            throw new IllegalStateException(
                    "postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
        }
        if (this.factoriesPostProcessed.contains(registryId)) {
            throw new IllegalStateException(
                    "postProcessBeanFactory already called on this post-processor against " + registry);
        }
        this.registriesPostProcessed.add(registryId);

        processConfigBeanDefinitions(registry);
    }
}

通过上面发现,BeanDefinition实例的注册是通过ConfigurationClassPostProcessor类的后置处理方法processConfigBeanDefinitions(registry);方法来处理。

继续深入processConfigBeanDefinitions(registry)方法

public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
        PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {

    public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
        //1.初始化BeanDefinitionHolder集合
        List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
        //2.所有已经注册的bean
        String[] candidateNames = registry.getBeanDefinitionNames();

        //3.遍历已注册的bean数组
        for (String beanName : candidateNames) {
            //得到BeanDefinition实例
            BeanDefinition beanDef = registry.getBeanDefinition(beanName);
            if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
                //如果BeanDefinition 中的configurationClass 属性为full 或者lite ,则意味着已经处理过了,直接跳过
                if (logger.isDebugEnabled()) {
                    logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
                }
            }
            else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
                //带有@Configuration注解的bean添加到集合中
                // 判断对应bean是否为配置类,如果是,则加入到configCandidates
                configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
            }
        }

        // Return immediately if no @Configuration classes were found
        if (configCandidates.isEmpty()) {
            //两种都不满足,配置类已经被处理了
            return;
        }

        // Sort by previously determined @Order value, if applicable
        // 对configCandidates 进行 排序,按照@Order 配置的值进行排序
        configCandidates.sort((bd1, bd2) -> {
            int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
            int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
            return Integer.compare(i1, i2);
        });

        // Detect any custom bean name generation strategy supplied through the enclosing application context
        // 如果BeanDefinitionRegistry 是SingletonBeanRegistry 的子类的话,
        // 由于我们当前传入的是DefaultListableBeanFactory,它是
        // SingletonBeanRegistry 的子类。因此会将registry强转为SingletonBeanRegistry
        SingletonBeanRegistry sbr = null;
        if (registry instanceof SingletonBeanRegistry) {
            sbr = (SingletonBeanRegistry) registry;
            if (!this.localBeanNameGeneratorSet) {
                BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
                        AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
                if (generator != null) {
                    this.componentScanBeanNameGenerator = generator;
                    this.importBeanNameGenerator = generator;
                }
            }
        }

        //web应用为StandardServletEnvironment
        if (this.environment == null) {
            this.environment = new StandardEnvironment();
        }

        // Parse each @Configuration class
        //初始化一个ConfigurationClassParser解析器,可以解析@Congiguration配置类
        ConfigurationClassParser parser = new ConfigurationClassParser(
                this.metadataReaderFactory, this.problemReporter, this.environment,
                this.resourceLoader, this.componentScanBeanNameGenerator, registry);
        //List转成Set
        Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
        //初始化一个已经解析的HashSet
        Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
        //循环解析,直到candidates为空
        do {
            //核心:解析
            parser.parse(candidates);
            //主要校验配置类不能使用final修饰符(CGLIB代理是生成一个子类,因此原先的类不能使用final修饰)
            //if (this.getMetadata().isAnnotated(Configuration.class.getName()) && this.getMetadata().isFinal())
            parser.validate();
            //排除已处理过的配置类
            Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
            configClasses.removeAll(alreadyParsed);

            // Read the model and create bean definitions based on its content
            //读取模型并根据其内容创建bean定义
            if (this.reader == null) {
                this.reader = new ConfigurationClassBeanDefinitionReader(
                        registry, this.sourceExtractor, this.resourceLoader, this.environment,
                        this.importBeanNameGenerator, parser.getImportRegistry());
            }
            //2.加载bean定义信息,主要实现将@Configuration @Import @ImportResource @ImportRegistrar注册为bean
            this.reader.loadBeanDefinitions(configClasses);
            //将configClasses加入到已解析alreadyParsed中
            alreadyParsed.addAll(configClasses);
            //清空已处理的配置类
            candidates.clear();
            //再次获取容器中bean定义数量  如果大于 之前获取的bean定义数量,则说明有新的bean注册到容器中,需要再次解析
            //getBeanDefinitionCount()取得是registry.beanDefinitionMap.size()
            if (registry.getBeanDefinitionCount() > candidateNames.length) {
                //容器中新的所有已注册的bean(包括老的)
                String[] newCandidateNames = registry.getBeanDefinitionNames();
                //容器中老的已注册的bean(已经解析了)
                Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
                //用来存储已经解析的类
                Set<String> alreadyParsedClasses = new HashSet<>();
                //循环遍历把已解析的类放到alreadyParsedClasses中
                for (ConfigurationClass configurationClass : alreadyParsed) {
                    alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
                }

                //循环遍历新的所有已注册的bean,排除老的已解析的,再过滤是否是配置类带有@Configuration,并且没有解析过,添加到candidates中,
                //下一次可以再处理解析
                for (String candidateName : newCandidateNames) {
                    if (!oldCandidateNames.contains(candidateName)) {
                        BeanDefinition bd = registry.getBeanDefinition(candidateName);
                        if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
                                !alreadyParsedClasses.contains(bd.getBeanClassName())) {
                            candidates.add(new BeanDefinitionHolder(bd, candidateName));
                        }
                    }
                }
                candidateNames = newCandidateNames;
            }
        }
        while (!candidates.isEmpty());

        // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
        if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
            sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
        }

        if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
            // Clear cache in externally provided MetadataReaderFactory; this is a no-op
            // for a shared cache since it'll be cleared by the ApplicationContext.
            ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
        }
    }
}

parser.parse(candidates)对配置类的解析

class ConfigurationClassParser {

    private final DeferredImportSelectorHandler deferredImportSelectorHandler = new DeferredImportSelectorHandler();

    public void parse(Set<BeanDefinitionHolder> configCandidates) {
        //循环遍历需要处理的配置类
        for (BeanDefinitionHolder holder : configCandidates) {
            BeanDefinition bd = holder.getBeanDefinition();

            //根据BeanDefinition实例判断调用哪个,其实最后还是调用
            //核心方法:processConfigurationClass(ConfigurationClass configClass)
            try {
                if (bd instanceof AnnotatedBeanDefinition) {
                    parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
                }
                else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
                    parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
                }
                else {
                    parse(bd.getBeanClassName(), holder.getBeanName());
                }
            }
            catch (BeanDefinitionStoreException ex) {
                throw ex;
            }
            catch (Throwable ex) {
                throw new BeanDefinitionStoreException(
                        "Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
            }
        }

        //字面理解:处理延迟导入的javabean
        //parse方法,把被处理的类实现DeferredImportSelector接口,加入deferredImportSelectors集合中,
        //处理deferredImportSelectors集合种类
        this.deferredImportSelectorHandler.process();
    }
}

继续深入其中的一个parse()方法

class ConfigurationClassParser {

    protected final void parse(@Nullable String className, String beanName) throws IOException {
        Assert.notNull(className, "No bean class name for configuration class bean definition");
        MetadataReader reader = this.metadataReaderFactory.getMetadataReader(className);
        processConfigurationClass(new ConfigurationClass(reader, beanName), DEFAULT_EXCLUSION_FILTER);
    }

    protected final void parse(Class<?> clazz, String beanName) throws IOException {
        processConfigurationClass(new ConfigurationClass(clazz, beanName), DEFAULT_EXCLUSION_FILTER);
    }

    protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
        processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
    }
}

parse调用核心方法processConfigurationClass(ConfigurationClass configClass)解析

class ConfigurationClassParser {

    protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
        //检查当前解析的配置bean是否包含Conditional注解,如果不包含则不需要跳过
        // 如果包含了则进行match方法得到匹配结果,如果是符合的并且设置的配置解析策略是解析阶段不需要调过
        if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
            return;
        }

        //在这里处理Configuration重复import
        //如果同一个配置类被处理两次,两次都属于被import的则合并导入类,返回。如果配置类不是被导入的,则移除旧使用新的配置类
        ConfigurationClass existingClass = this.configurationClasses.get(configClass);
        if (existingClass != null) {
            if (configClass.isImported()) {
                if (existingClass.isImported()) {
                    existingClass.mergeImportedBy(configClass);
                }
                // Otherwise ignore new imported config class; existing non-imported class overrides it.
                return;
            }
            else {
                // Explicit bean definition found, probably replacing an import.
                // Let's remove the old one and go with the new one.
                this.configurationClasses.remove(configClass);
                this.knownSuperclasses.values().removeIf(configClass::equals);
            }
        }

        // Recursively process the configuration class and its superclass hierarchy.
        SourceClass sourceClass = asSourceClass(configClass, filter);
        //递归解析
        do {
            sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
        }
        while (sourceClass != null);

        // 添加到ConfigurationClassParser的configurationClasses中
        this.configurationClasses.put(configClass, configClass);
    }
}

递归解析,调用doProcessConfigurationClass方法,终于到了解析的地方,继续深入

class ConfigurationClassParser {

    protected final SourceClass doProcessConfigurationClass(
            ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
            throws IOException {

        if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
            // Recursively process any member (nested) classes first 处理内部类
            processMemberClasses(configClass, sourceClass, filter);
        }

        // Process any @PropertySource annotations
        // 处理@PropertySource注解
        for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
                sourceClass.getMetadata(), PropertySources.class,
                org.springframework.context.annotation.PropertySource.class)) {
            if (this.environment instanceof ConfigurableEnvironment) {
                processPropertySource(propertySource);
            }
            else {
                logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
                        "]. Reason: Environment must implement ConfigurableEnvironment");
            }
        }

        // Process any @ComponentScan annotations
        // 处理@ComponentScan注解
        Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
                sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
        if (!componentScans.isEmpty() &&
                !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
            //扫描
            for (AnnotationAttributes componentScan : componentScans) {
                // The config class is annotated with @ComponentScan -> perform the scan immediately
                Set<BeanDefinitionHolder> scannedBeanDefinitions =
                        this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
                // Check the set of scanned definitions for any further config classes and parse recursively if needed
                //遍历扫描到的配置类进行递归解析
                for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
                    BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
                    if (bdCand == null) {
                        bdCand = holder.getBeanDefinition();
                    }
                    if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
                        parse(bdCand.getBeanClassName(), holder.getBeanName());
                    }
                }
            }
        }

        // Process any @Import annotations
        // 处理@Import注解
        processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

        // Process any @ImportResource annotations
        // 处理@ImportResource 注解
        AnnotationAttributes importResource =
                AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
        if (importResource != null) {
            String[] resources = importResource.getStringArray("locations");
            Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
            // 遍历配置的locations,加入到configClass 中的ImportedResource
            for (String resource : resources) {
                String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
                configClass.addImportedResource(resolvedResource, readerClass);
            }
        }

        // Process individual @Bean methods
        // 处理@Bean修饰的方法
        Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
        for (MethodMetadata methodMetadata : beanMethods) {
            configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
        }

        // Process default methods on interfaces
        // 处理接口定义的方法
        processInterfaces(configClass, sourceClass);

        // Process superclass, if any
        if (sourceClass.getMetadata().hasSuperClass()) {
            String superclass = sourceClass.getMetadata().getSuperClassName();
            if (superclass != null && !superclass.startsWith("java") &&
                    !this.knownSuperclasses.containsKey(superclass)) {
                this.knownSuperclasses.put(superclass, configClass);
                // Superclass found, return its annotation metadata and recurse
                return sourceClass.getSuperClass();
            }
        }

        // No superclass -> processing is complete
        return null;
    }
}

解析doProcessConfigurationClass方法,总结一下:

  • 1、处理内部类
  • 2、处理@PropertySource注解
  • 3、处理@ComponentScan注解
  • 4、处理@Import注解
  • 5、处理@ImportResource注解
  • 6、处理@Bean修饰的方法
  • 7、处理接口定义的方法
  • 8、处理父类

1、处理内部类(递归解析)

class ConfigurationClassParser {

    /**
     * Register member (nested) classes that happen to be configuration classes themselves.
     * 处理内部类
     */
    private void processMemberClasses(ConfigurationClass configClass, SourceClass sourceClass,
            Predicate<String> filter) throws IOException {
        //读取配置类中所有成员类
        Collection<SourceClass> memberClasses = sourceClass.getMemberClasses();
        if (!memberClasses.isEmpty()) {
            List<SourceClass> candidates = new ArrayList<>(memberClasses.size());
            for (SourceClass memberClass : memberClasses) {
                //过滤出配置类
                if (ConfigurationClassUtils.isConfigurationCandidate(memberClass.getMetadata()) &&
                        !memberClass.getMetadata().getClassName().equals(configClass.getMetadata().getClassName())) {
                    candidates.add(memberClass);
                }
            }
            //根据Order进行排序
            OrderComparator.sort(candidates);
            //遍历
            for (SourceClass candidate : candidates) {
                //出现配置类循环导入,直接报错
                if (this.importStack.contains(configClass)) {
                    this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
                }
                else {
                    //将配置类入栈
                    this.importStack.push(configClass);
                    try {
                        //处理配置类
                        processConfigurationClass(candidate.asConfigClass(configClass), filter);
                    }
                    finally {
                        //解析完出栈
                        this.importStack.pop();
                    }
                }
            }
        }
    }
}

2、处理@PropertySource注解

如果配置类上有@PropertySource注解,则解析加载properties文件,并将属性添加到Spring上下文中。
深入processPropertySource(propertySource)方法

class ConfigurationClassParser {

    private void processPropertySource(AnnotationAttributes propertySource) throws IOException {
        String name = propertySource.getString("name");
        if (!StringUtils.hasLength(name)) {
            name = null;
        }
        String encoding = propertySource.getString("encoding");
        if (!StringUtils.hasLength(encoding)) {
            encoding = null;
        }
        String[] locations = propertySource.getStringArray("value");
        Assert.isTrue(locations.length > 0, "At least one @PropertySource(value) location is required");
        boolean ignoreResourceNotFound = propertySource.getBoolean("ignoreResourceNotFound");

        Class<? extends PropertySourceFactory> factoryClass = propertySource.getClass("factory");
        PropertySourceFactory factory = (factoryClass == PropertySourceFactory.class ?
                DEFAULT_PROPERTY_SOURCE_FACTORY : BeanUtils.instantiateClass(factoryClass));

        for (String location : locations) {
            try {
                String resolvedLocation = this.environment.resolveRequiredPlaceholders(location);
                Resource resource = this.resourceLoader.getResource(resolvedLocation);
                addPropertySource(factory.createPropertySource(name, new EncodedResource(resource, encoding)));
            }
            catch (IllegalArgumentException | FileNotFoundException | UnknownHostException ex) {
                // Placeholders not resolvable or resource not found when trying to open it
                if (ignoreResourceNotFound) {
                    if (logger.isInfoEnabled()) {
                        logger.info("Properties location [" + location + "] not resolvable: " + ex.getMessage());
                    }
                }
                else {
                    throw ex;
                }
            }
        }
    }

    private void addPropertySource(PropertySource<?> propertySource) {
        String name = propertySource.getName();
        MutablePropertySources propertySources = ((ConfigurableEnvironment) this.environment).getPropertySources();

        //如果存在同名的PropertySource,
        // 则使用CompositePropertySource替换原来的PropertySource,
        // 而CompositePropertySource中包含了所有的PropertySource
        if (this.propertySourceNames.contains(name)) {
            // We've already added a version, we need to extend it
            PropertySource<?> existing = propertySources.get(name);
            if (existing != null) {
                PropertySource<?> newSource = (propertySource instanceof ResourcePropertySource ?
                        ((ResourcePropertySource) propertySource).withResourceName() : propertySource);
                if (existing instanceof CompositePropertySource) {
                    //将新的PropertySource添加到第一个,使用时在该组中最后一个使用。
                    ((CompositePropertySource) existing).addFirstPropertySource(newSource);
                }
                else {
                    if (existing instanceof ResourcePropertySource) {
                        existing = ((ResourcePropertySource) existing).withResourceName();
                    }
                    CompositePropertySource composite = new CompositePropertySource(name);
                    composite.addPropertySource(newSource);
                    composite.addPropertySource(existing);
                    propertySources.replace(name, composite);
                }
                return;
            }
        }

        /**
         * 如果没有同名的PropertySource,当只有一个的时候,直接添加到propertySources中
         * 否则将新的PropertySource添加到除systemProperties
         * systemEnvironment变量紧接着的第一个(意思就是后添加的后使用,但是如果他们存在同名的属性,后使用的PropertySource会覆盖先使用的)
         */
        if (this.propertySourceNames.isEmpty()) {
            propertySources.addLast(propertySource);
        }
        else {
            /**
             * propertySourceNames中存放的是自定义的PropertySource name,不包含systemProperties systemEnvironment
             * 因此每次添加的新PropertySource都是在列表中的第三个(得出此结论的前提框架不在添加其他默认的PropertySource)
             */
            String firstProcessed = this.propertySourceNames.get(this.propertySourceNames.size() - 1);
            propertySources.addBefore(firstProcessed, propertySource);
        }
        this.propertySourceNames.add(name);
    }
}

3、处理@ComponentScan注解

获取配置类上的@ComponentScan注解,判断是否需要跳过。循环所有的ComponentScan,立即执行扫描。

// Process any @ComponentScan annotations
// 处理@ComponentScan注解
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
        sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
        !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
    //扫描
    for (AnnotationAttributes componentScan : componentScans) {
        // The config class is annotated with @ComponentScan -> perform the scan immediately
        Set<BeanDefinitionHolder> scannedBeanDefinitions =
                this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
        // Check the set of scanned definitions for any further config classes and parse recursively if needed
        //遍历扫描到的配置类进行递归解析
        for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
            BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
            if (bdCand == null) {
                bdCand = holder.getBeanDefinition();
            }
            //检验扫描获得的BeanDefinition中是否有配置类,如果有配置类,这里的配置类包括FullConfigurationClass和LiteConfigurationClass。
            //(也就是说只要有@Configuration、@Component、@ComponentScan、@Import、@ImportResource和@Bean中的其中一个注解),则递归调用parse方法,进行解析。
            if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
                parse(bdCand.getBeanClassName(), holder.getBeanName());
            }
        }
    }
}
继续深入分析
Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
class ComponentScanAnnotationParser {

    private final Environment environment;

    private final ResourceLoader resourceLoader;

    private final BeanDefinitionRegistry registry;

    public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
        //根据@ComponentScan的useDefaultFilters值来构建一个ClassPathBeanDefinitionScanner
        //默认为true  如果为true 会注册一些默认的注解过滤器,例如@Component @ManagedBean 和 @Named
        ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
                componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);

        //类名生成器,默认为BeanNameGenerator接口
        Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
        boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
        //为scanner设置类名生成器,默认为AnnotationBeanNameGenerator  如果不填则为类名且首字母小写
        scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
                BeanUtils.instantiateClass(generatorClass));

        ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
        //scopedProxy默认为DEFAULT
        if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
            scanner.setScopedProxyMode(scopedProxyMode);
        }
        else {
            //scopeResolver默认为AnnotationScopeMetadataResolver
            Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
            scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
        }
        //设置资源匹配器  默认为**/*.class   即所有class
        scanner.setResourcePattern(componentScan.getString("resourcePattern"));
        //找到所有的设置的filter 默认为空
        for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
            for (TypeFilter typeFilter : typeFiltersFor(filter)) {
                scanner.addIncludeFilter(typeFilter);
            }
        }

        //找到所有排除的filter ,springboot默认有TypeExcludeFilter和AutoConfigurationExcludeFilter
        for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
            for (TypeFilter typeFilter : typeFiltersFor(filter)) {
                scanner.addExcludeFilter(typeFilter);
            }
        }
        //是否懒加载 默认为false
        boolean lazyInit = componentScan.getBoolean("lazyInit");
        if (lazyInit) {
            scanner.getBeanDefinitionDefaults().setLazyInit(true);
        }

        Set<String> basePackages = new LinkedHashSet<>();
        //找到所有的扫描路径
        String[] basePackagesArray = componentScan.getStringArray("basePackages");
        //解析每个路径 默认这儿为空
        for (String pkg : basePackagesArray) {
            //解析这些路径
            String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
                    ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
            //将解析出来的路径添加到原有的路径中
            Collections.addAll(basePackages, tokenized);
        }
        //如果有basePackageClasses则添加  默认为null
        for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
            basePackages.add(ClassUtils.getPackageName(clazz));
        }
        //如果上述的全部为空  则添加声明类的所在包
        //这也就是为何@SpringbootApplication默认只解析其所在的包下面的所有的类,其上级包没法解决
        if (basePackages.isEmpty()) {
            basePackages.add(ClassUtils.getPackageName(declaringClass));
        }
        //将传入的类本身排除掉
        scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
            @Override
            protected boolean matchClassName(String className) {
                return declaringClass.equals(className);
            }
        });

        //进行扫描
        return scanner.doScan(StringUtils.toStringArray(basePackages));
    }
}

这个方法很长,但内容很简单,无非就是挨个解析@ComponentScan的值并将其设置到ClassPathBeanDefinitionScanner中,然后调用scanner的解析方法,这儿有两点需要注意

  • 1、默认的includeFilter中加入了@Component注解,这个非常重要
  • 2、如果注解中没有找到任何可用的basePackage,那么会默认使用传入类的package作为basePackage,而这儿第一次进来的一般为主启动类,所以@springbootApplication之所以默认是解析其类所在的包下所有的类的缘由就在于此。
然后我们接着看doScan方法
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {

    private BeanNameGenerator beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;

    private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();

    protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
        //做下判空
        Assert.notEmpty(basePackages, "At least one base package must be specified");
        //创建返回set
        Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
        //迭代每个basePackage
        for (String basePackage : basePackages) {
            //找到basePackage下所有的配置类
            Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
            //处理这次找到的所有配置类
            for (BeanDefinition candidate : candidates) {
                //获取其Scope信息,也就是分析其@Scope注解
                ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
                //设置其scope
                candidate.setScope(scopeMetadata.getScopeName());
                //这儿会获取名字,如果没有默认为其类名且首字母小写
                String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
                //如果配置类的BeanDefinition继承了AbstractBeanDefinition
                if (candidate instanceof AbstractBeanDefinition) {
                    //则为这个candidate根据刚才初始化时构建的beanDefinitionDefaults来设置BeanDefinition一些属性,
                    //例如是否懒加载,自动装配模型等
                    postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
                }
                //如果配置类 的BeanDefinition实现了AnnotatedBeanDefinition接口
                //例如有@Lazy  @Primary @DependsOn @Role @Description等注解
                if (candidate instanceof AnnotatedBeanDefinition) {
                    //那么就对其每个注解进行特定的处理  例如Lazy设置懒加载
                    // 例如Primary设置该类为主要类(例如一个接口有多个实现时,某个实现类加上这个就可以直接使用@Autowire注解不会报错)
                    AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
                }
                //检查一下该配置类是否在registray中已存在。为true则代表无冲突,否则会报异常
                //例如两个类名一样且都使用@Component注解没有指定姓名就会报错这儿
                if (checkCandidate(beanName, candidate)) {
                    //如果没问题则构造一个BeanDefinitionHolder
                    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
                    //这儿是根据scope信息来判定是否需要需要生成代理  默认不生成
                    //如果要生成可以为配置类加上@Scope(proxyMode = ScopedProxyMode.DEFAULT) 即可//只要不为ScopedProxyMode.NO(默认属性)即可
                    definitionHolder =
                            AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
                    beanDefinitions.add(definitionHolder);
                    //将该配置类注入到spring的registry中
                    registerBeanDefinition(definitionHolder, this.registry);
                }
            }
        }
        return beanDefinitions;
    }
}

这个方法主要就是根据basePackage找到所有的配置类并创建BeanDefinition返回,然后为BeanDefinition设置一些必要的属性,最后根据特定的注解做一些特殊的判断即可。最后这些配置类代表的BeanDefinitionHolder 会被添加到spring的regitry中,在后面实例化的时候将会有很大的作用。

那我们还是接着看下basePackage下的Bean是如何被找到的,我们接着看findCandidateComponents方法。

public class ClassPathScanningCandidateComponentProvider implements EnvironmentCapable, ResourceLoaderAware {
    
    public Set<BeanDefinition> findCandidateComponents(String basePackage) {
        if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
            return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
        }
        else {
            return scanCandidateComponents(basePackage);
        }
    }

    private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
        Set<BeanDefinition> candidates = new LinkedHashSet<>();
        try {
            //找到解析的路径匹配规则  resourcePattern默认为**/*.class   即所有的class
            String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
                    resolveBasePackage(basePackage) + '/' + this.resourcePattern;
            //根据路径去循环递归查找路径所包含的每一个class文件
            Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
            boolean traceEnabled = logger.isTraceEnabled();
            boolean debugEnabled = logger.isDebugEnabled();
            for (Resource resource : resources) {
                if (traceEnabled) {
                    logger.trace("Scanning " + resource);
                }
                //循环处理每个可读的class文件
                if (resource.isReadable()) {
                    try {
                        //读取文件的元数据
                        MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
                        //如果文件在includeFilter中  且没有包含在excludeFilters中 则说明是我们需要加入到容器中的配置类
                        if (isCandidateComponent(metadataReader)) {
                            //新建ScannedGenericBeanDefinition  (注意其实现了AnnotatedBeanDefinition接口,且集成了AbstractBeanDefinition类)
                            ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
                            sbd.setSource(resource);
                            if (isCandidateComponent(sbd)) {
                                if (debugEnabled) {
                                    logger.debug("Identified candidate component class: " + resource);
                                }
                                candidates.add(sbd);
                            }
                            else {
                                if (debugEnabled) {
                                    logger.debug("Ignored because not a concrete top-level class: " + resource);
                                }
                            }
                        }
                        else {
                            if (traceEnabled) {
                                logger.trace("Ignored because not matching any filter: " + resource);
                            }
                        }
                    }
                    catch (Throwable ex) {
                        throw new BeanDefinitionStoreException(
                                "Failed to read candidate component class: " + resource, ex);
                    }
                }
                else {
                    if (traceEnabled) {
                        logger.trace("Ignored because not readable: " + resource);
                    }
                }
            }
        }
        catch (IOException ex) {
            throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
        }
        //返回
        return candidates;
    }
}

这个方法就很简单了,系统解析了路径,并找到路径下所有的class文件,那么spring怎么知道哪些是需要加载配置的呢,这时在上面着重让大家记住的includeFilter就起作用了,由于其加入了@Component注解的支持,我们看这个isCandidateComponent方法。

protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
    for (TypeFilter tf : this.excludeFilters) {
        if (tf.match(metadataReader, getMetadataReaderFactory())) {
            return false;
        }
    }
    for (TypeFilter tf : this.includeFilters) {
        if (tf.match(metadataReader, getMetadataReaderFactory())) {
            return isConditionMatch(metadataReader);
        }
    }
    return false;
}

看了这个方法相信大家就了然了,只有includeFilter为true才会返回true,这儿还有点需要注意的是isConditionMatch,这个处理的是@Conditional系列的注解,用来判定是否满足加载配置的条件。如果不满足则不必加载,会返回false。

来看component-scan的几个属性
  • basePackages:Spring将扫描的基础package名,Spring会扫描该包以及其子孙包下的所有类。

  • useDefaultFilters:默认为true,此时Spring扫描类时发现如果其被标注为 @Component、@Repository、@Service、@Controller则自动实例化为bean并将其添加到上下文中,如果设置为false,即使将其标注为@Component或者其他,Spring都会忽略。

  • includeFilters:指定扫描时需要实例化的类型,我们可以从名字看到这是一个Filter,你可以自己定义该Filter,Spring为我们提供了一套方便的实现,我们可以根据标注、类、包等相关信息决定当扫描到该类时是否需要实例化该类,需要注意的是如果你仅仅想扫描如@Controller不仅要加includeFilters,还需要将useDefaultFilters设置为false

  • excludeFilter:指定扫描到某个类时需要忽略它,实现和上一个Filter一样,区别只是如果Filter匹配,Spring会忽略该类。

这样includeFilters以及excludeFilterF的行为就很清楚了,Spring每扫描一个类,都会经过includeFilters以及excludeFilters,如果某个Filter匹配,就执行相应的操作(实例化或者忽略)。

接着回到doScan方法中,该方法最后会调用registerBeanDefinition(definitionHolder, this.registry)方法,将扫描出来的BeanDefinition注册到到spring的容器中
//将该配置类注入到spring的registry中
registerBeanDefinition(definitionHolder, this.registry);
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {

    protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) {
        BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
    }
}

public abstract class BeanDefinitionReaderUtils {

    public static void registerBeanDefinition(
            BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
            throws BeanDefinitionStoreException {

        // Register bean definition under primary name.
        // 使用beanName做唯一标识注册
        String beanName = definitionHolder.getBeanName();
        registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

        // Register aliases for bean name, if any.
        // 注册所有的别名
        String[] aliases = definitionHolder.getAliases();
        if (aliases != null) {
            for (String alias : aliases) {
                registry.registerAlias(beanName, alias);
            }
        }
    }
}
  • 最终将解析出来的BeanDefinition封装到BeanDefinitionHolder中,由BeanDefinitionReaderUtils的registerBeanDefinition方法将BeanDefinition注册到Spring IOC容器中。
  • 最终调用DefaultListableBeanFactory类的registerBeanDefinition方法将beanDefinition注册到beanDefinitionMap中。

阶段总结

到这个地方为止,@ComponentScan 就真正扫描完成了,BeanDefinition 也加载完成了。

从解析 parser.parse 方法开始,到最后注册 BeanDefinition 为止:


image.png

4、处理@Import注解

processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

processImports方法负责对@Import注解进行解析。configClass是配置类,sourceClass又是通过configClass创建的,getImports(sourceClass)从sourceClass获取所有的@Import注解信息

class ConfigurationClassParser {

    private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
            Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
            boolean checkForCircularImports) {

        if (importCandidates.isEmpty()) {
            return;
        }

        //循环导入直接报错
        if (checkForCircularImports && isChainedImportOnStack(configClass)) {
            this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
        }
        else {
            //推入栈
            this.importStack.push(configClass);
            try {
                //循环遍历
                for (SourceClass candidate : importCandidates) {
                    //对import的内容进行分类
                    // import导入实现ImportSelector接口的类
                    if (candidate.isAssignable(ImportSelector.class)) {
                        // Candidate class is an ImportSelector -> delegate to it to determine imports
                        Class<?> candidateClass = candidate.loadClass();
                        // 反射创建这个类的实例对象
                        ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,
                                this.environment, this.resourceLoader, this.registry);
                        //是否有实现相关Aware接口,如果有,这调用相关方法
                        Predicate<String> selectorFilter = selector.getExclusionFilter();
                        // 延迟加载的ImportSelector
                        if (selectorFilter != null) {
                            exclusionFilter = exclusionFilter.or(selectorFilter);
                        }
                        if (selector instanceof DeferredImportSelector) {
                            //  延迟加载的ImportSelector先放到List中,延迟加载
                            this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
                        }
                        else {
                            // 普通的ImportSelector ,执行其selectImports方法,获取需要导入的类的全限定类名数组
                            String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
                            Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
                            // 递归调用
                            processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
                        }
                    }
                    // 是否为ImportBeanDefinitionRegistrar
                    else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
                        // Candidate class is an ImportBeanDefinitionRegistrar ->
                        // delegate to it to register additional bean definitions
                        Class<?> candidateClass = candidate.loadClass();
                        ImportBeanDefinitionRegistrar registrar =
                                ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
                                        this.environment, this.resourceLoader, this.registry);
                        // 添加到成员变量
                        configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
                    }
                    else {
                        // Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
                        // process it as an @Configuration class
                        // 普通 @Configuration class
                        this.importStack.registerImport(
                                currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
                        // 解析导入的@Configuration class
                        processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
                    }
                }
            }
            catch (BeanDefinitionStoreException ex) {
                throw ex;
            }
            catch (Throwable ex) {
                throw new BeanDefinitionStoreException(
                        "Failed to process import candidates for configuration class [" +
                        configClass.getMetadata().getClassName() + "]", ex);
            }
            finally {
                this.importStack.pop();
            }
        }
    }
}

5、处理@ImportResource注解

@ImportResource注解可以导入xml配置文件。

// Process any @Import annotations
// 处理@Import注解
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

// Process any @ImportResource annotations
// 处理@ImportResource 注解
AnnotationAttributes importResource =
        AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
    String[] resources = importResource.getStringArray("locations");
    Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
    // 遍历配置的locations,加入到configClass 中的ImportedResource
    for (String resource : resources) {
        String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
        //把配置项提取出来,跟reader一起放入configClass的map中,
        //接下来会在ConfigurationClassPostProcessor类中processConfigBeanDefinitions方法中,解析完,
        //this.reader.loadBeanDefinitions(configClasses)这方法会对@import处理(对ImportBeanDefinitionRegistrars的处理)
        configClass.addImportedResource(resolvedResource, readerClass);
    }
}

6、处理@Bean修饰的方法

// Process individual @Bean methods
// 处理@Bean修饰的方法
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
    //添加到configClass的beanMethods集合中,接下来,会在this.reader.loadBeanDefinitions(configClasses)这方法
    //得到处理
    configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}

7、处理接口定义的方法

// Process default methods on interfaces
// 处理接口定义的方法
processInterfaces(configClass, sourceClass);

8、处理父类

// Process superclass, if any
// 8.如果有父类则递归读取父类
if (sourceClass.getMetadata().hasSuperClass()) {
    String superclass = sourceClass.getMetadata().getSuperClassName();
    if (superclass != null && !superclass.startsWith("java") &&
            !this.knownSuperclasses.containsKey(superclass)) {
        this.knownSuperclasses.put(superclass, configClass);
        // Superclass found, return its annotation metadata and recurse
        return sourceClass.getSuperClass();
    }
}

// No superclass -> processing is complete
// 没有父类直接返回
return null;

参考:
https://www.abboke.com/jsh/2019/0628/4154.html

https://www.cnblogs.com/ZhuChangwu/p/11674684.html

https://blog.csdn.net/tuoni123/article/details/79976105

https://www.cnblogs.com/TimeSay/p/10874476.html

https://zhuanlan.zhihu.com/p/83473498

https://www.cnblogs.com/hello-shf/p/10987360.html

https://www.cnblogs.com/duanxz/p/11239291.html

https://www.cnblogs.com/mufeng07/p/12165616.html

https://www.cnblogs.com/mufeng07/p/12172549.html

https://www.cnblogs.com/hetutu-5238/p/12378432.html

https://blog.csdn.net/xujingyiss/article/details/119705692

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335