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


    本文涉及主题

    1. BeanFactoryPostProcessor调用过程源码剖析

    2. 配置类的解析过程源码

    3. 配置类@Configuration加与不加的区别

    4. 重复beanName的覆盖规则

    5. @ComponentScan的解析原理


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

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

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

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

    第一件事: 调用this()自身的无参构造函数. 初始化了BeanDefinitionReader和BeanDefinitionScanner, 同时初始化了很多spring的原始后置处理器, 这些处理器是用来加载bean的

    第二件事: 调用register(..) 注册配置类

    第三件事: refresh(..) 这里包含了整个ioc创建bean的全生命周期, 今天重点看invokeBeanFactoryPostProcessors(beanFactory)加载配置类

    二. 准备工作: 自定义配置类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<BeanDefinitionHolder> registerAnnotationConfigProcessors(
                BeanDefinitionRegistry registry, @Nullable Object source) {
    
            // 获取到beanFactory
            DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
            /**
             * 判断beanFactory中是否有AnnotationAwareOrderComparator和ContextAnnotationAutowireCandidateResolver
             * 没有则添加
             */
            if (beanFactory != null) {
                if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
                    beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
                }
                if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
                    beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
                }
            }
    
            // BeanDefinitionHolder: 为BeanDefinition设置名字和别名
            Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
    
            // 如果registry中没有ConfigurationClassPostProcessor配置类后置处理器, 就添加一个
            if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
                def.setSource(source);
                // 构建BeanDefinitionHolder, 并添加到beanDefs
                beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
            }
    
            // 如果rigistry中, 没有AutowiredAnnotationBeanPostProcessor  Autowired注解bean的后置处理器, 则添加一个
            if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
                def.setSource(source);
                // 构建BeanDefinitionHolder, 并添加到beanDefs
                beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
            }
    
            // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
            // 检查对JSR-250的支持, 如果rigistry中没有 CommonAnnotationBeanPostProcessor 通用注解后置处理器, 则添加一个
            if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
                def.setSource(source);
                // 构建BeanDefinitionHolder, 并添加到beanDefs
                beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
            }
    
            // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
            // 检查对jpa的支持, 如果不包含 internalPersistenceAnnotationProcessor, 持久化注解处理器, 就添加一个
            if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition();
                try {
                    def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
                            AnnotationConfigUtils.class.getClassLoader()));
                }
                catch (ClassNotFoundException ex) {
                    throw new IllegalStateException(
                            "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
                }
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
            }
    
            // 检查对事件监听的支持, 如果不包含事件监听处理器 internalEventListenerProcessor, 就添加一个
            if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
            }
    
            // 如果不包含事件监听工厂处理器 internalEventListenerFactory , 就添加一个
            if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
            }
    
            return beanDefs;
        }

    我们看到, 注册了6个原始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<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
                        updatedDefinitions.addAll(this.beanDefinitionNames);
                        updatedDefinitions.add(beanName);
                        this.beanDefinitionNames = updatedDefinitions;
                        removeManualSingletonName(beanName);
                    }
                }
                else {
                    // Still in startup registration phase
                    this.beanDefinitionMap.put(beanName, beanDefinition);
                    this.beanDefinitionNames.add(beanName);
                    removeManualSingletonName(beanName);
                }
                this.frozenBeanDefinitionNames = null;
            }
    
            if (existingDefinition != null || containsSingleton(beanName)) {
                resetBeanDefinition(beanName);
            }
            else if (isConfigurationFrozen()) {
                clearByTypeCache();
            }
        }

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

    下面的else是处理循环引用的问题, 暂时先不要看. 

     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 <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
                @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
                @Nullable BeanDefinitionCustomizer[] customizers) {
    
            // 将入参的配置类beanClass构建成AnnotatedGenericBeanDefinition对象
            AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
            if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
                return;
            }
    
            abd.setInstanceSupplier(supplier);
            // 读取配置类的元数据
            ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
            abd.setScope(scopeMetadata.getScopeName());
            String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
    
            // 处理主类通用定义注解
            AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
            if (qualifiers != null) {
                for (Class<? extends Annotation> qualifier : qualifiers) {
                    if (Primary.class == qualifier) {
                        abd.setPrimary(true);
                    }
                    else if (Lazy.class == qualifier) {
                        abd.setLazyInit(true);
                    }
                    else {
                        abd.addQualifier(new AutowireCandidateQualifier(qualifier));
                    }
                }
            }
            if (customizers != null) {
                for (BeanDefinitionCustomizer customizer : customizers) {
                    customizer.customize(abd);
                }
            }
            // 将MainConfig.java配置类进行解析.放到BeanDefinitionHolder
            BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
            definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
            BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
        }

    重点就是红色这句话, 其他可以略过, 因为我们的配置类很简单, 直接看BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);

    我们找到 registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());方法, 进入到DefaultListableBeanFactory查看方法, 这个方法之前我们已经调用过一次

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

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

    以上两步, 一个是将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<BeanFactoryPostProcessor> 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<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
            /**
             * 首先,调用BeanDefinitionRegistryPostProcessors的后置处理器
             * 定义已处理的后置处理器
             */
            // Invoke BeanDefinitionRegistryPostProcessors first, if any.
            Set<String> processedBeans = new HashSet<>();
    
            /**
             * 这里一共分为两大步:
             * 第一步: 调用所有实现了 BeanDefinitionRegistryPostProcessor 接口的bean定义. (BeanDefinitionRegistryPostProcessor带注册功能的后置处理器)
             * 第二步: 调用BeanFactoryPostProcessor Bean工厂的后置处理器
             */
    
            /**********************第一步: 调用所有实现了BeanDefinitionRegistryPostProcessor接口的bean定义  begin****************************/
            // 判断beanFactory是否实现了BeanDefinitionRegistry, 实现了该结构就有注册和获取Bean定义的能力
            if (beanFactory instanceof BeanDefinitionRegistry) {
                BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
                List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
                List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
    
                for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                    if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                        BeanDefinitionRegistryPostProcessor registryProcessor =
                                (BeanDefinitionRegistryPostProcessor) postProcessor;
                        registryProcessor.postProcessBeanDefinitionRegistry(registry);
                        registryProcessors.add(registryProcessor);
                    }
                    else {
                        regularPostProcessors.add(postProcessor);
                    }
                }
    
                // Do not initialize FactoryBeans here: We need to leave all regular beans
                // uninitialized to let the bean factory post-processors apply to them!
                // Separate between BeanDefinitionRegistryPostProcessors that implement
                // PriorityOrdered, Ordered, and the rest.
                /**
                 * 这是一个集合, 存马上即将要被调用的BeanDefinitionRegistryPostProcessor
                 */
                List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
                // 第一步, 调用实现了PriorityOrdered的BeanDefinitionRegistryPostProcessors
                // 在所有创世纪的后置处理器中, 只有 internalConfigurationAnnotationProcessor 实现了 BeanDefinitionRegistryPostProcessors 和 PriorityOrdered
                // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
                String[] postProcessorNames =
                        beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    // 判断beanFactory是否实现了PriorityOrdered接口. 如果实现了,是最优先调用.
                    // 在整个加载过程中,会调用四次BeanDefinitionRegistryPostProcessor, 而实现了PriorityOrdered的接口最先调用
                    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                        // 调用beanFactory.getBean实例化创世界的类ppName
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                    }
                }
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                /**
                 * 第一次调用BeanDefinitionRegistryPostProcessors
                 * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor
                 * 用于进行bean定义的加载 比如我们的包扫描 @import 等
                 */
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                // 处理完了,清空currentRegistryProcessors
                currentRegistryProcessors.clear();
    
    
                // 第二步: 调用实现 Ordered 的 BeanDefinitionRegistryPostProcessors。
                // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    // 这时实现了PriorityOrdered.class的postProcessor就不会再被加载进来了, 因为processedBeans.contains(ppName) == true
                    if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                        // 将其放入到currentRegistryProcessors, 马上就要被调用
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                    }
                }
    
                // 对所有的处理器进行排序. 调用了Ordered的方法, 会返回排序(一个数字), 然后根据数字排序即可
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
    
                /**
                 * 第二次调用BeanDefinitionRegistryPostProcessors
                 * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor
                 * 用于进行bean定义的加载 比如我们的包扫描 @import 等
                 */
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();
    
    
                // 第三步. 调用没有实现任何优先级接口的 BeanDefinitionRegistryPostProcessor
                // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
                boolean reiterate = true;
                while (reiterate) {
                    reiterate = false;
                    // 获取
                    postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                    for (String ppName : postProcessorNames) {
                        // 已处理过的postProcessor不再处理
                        if (!processedBeans.contains(ppName)) {
                            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                            processedBeans.add(ppName);
                            reiterate = true;
                        }
                    }
                    sortPostProcessors(currentRegistryProcessors, beanFactory);
                    registryProcessors.addAll(currentRegistryProcessors);
                    /**
                     * 第三次调用BeanDefinitionRegistryPostProcessors
                     * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor
                     * 用于进行bean定义的加载 比如我们的包扫描 @import 等
                     */
                    invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                    currentRegistryProcessors.clear();
                }
    
                // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
                /*
                 * 第四步:调用bean工厂的后置处理器
                 * registryProcessors: 带有注册功能的bean工厂的后置处理器
                 * regularPostProcessors: 不带注册功能的bean工厂的后置处理器
                 */
                invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
                invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
            }
    
            else {
                /*
                 * 如果当前的beanFactory没有实现BeanDefinitionRegistry 说明没有注册Bean定义的能力
                 * 那么就直接调用 BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法
                 */
    
                // Invoke factory processors registered with the context instance.
                invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
            }
    
            /**********************第一步: 调用所有实现了BeanDefinitionRegistryPostProcessor接口的bean定义  end****************************/
    
            /**********************第二步: 调用BeanFactoryPostProcessor Bean工厂的后置处理器  begin****************************/
    
            // Do not initialize FactoryBeans here: We need to leave all regular beans
            // uninitialized to let the bean factory post-processors apply to them!
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    
            // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
            // Ordered, and the rest.
            // 优先排序的后置处理器
            List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
            List<String> orderedPostProcessorNames = new ArrayList<>();
            List<String> nonOrderedPostProcessorNames = new ArrayList<>();
            for (String ppName : postProcessorNames) {
                if (processedBeans.contains(ppName)) {
                    // skip - already processed in first phase above
                }
                else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
                }
                else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    orderedPostProcessorNames.add(ppName);
                }
                else {
                    nonOrderedPostProcessorNames.add(ppName);
                }
            }
    
            // 首先, 调用有优先级排序的后置处理器
            // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
            sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    
            // 第二, 调用实现了Ordered排序的后置处理器
            // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
            List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
            for (String postProcessorName : orderedPostProcessorNames) {
                orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
            }
            sortPostProcessors(orderedPostProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    
            // 最后, 调用没有实现任何排序接口的beanFactory后置处理器
            // Finally, invoke all other BeanFactoryPostProcessors.
            List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
            for (String postProcessorName : nonOrderedPostProcessorNames) {
                nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
            }
            invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    
            /**********************第二步: 调用BeanFactoryPostProcessor Bean工厂的后置处理器  end****************************/
            // Clear cached merged bean definitions since the post-processors might have
            // modified the original metadata, e.g. replacing placeholders in values...
            beanFactory.clearMetadataCache();
        }

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

     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

    2. 第二次调用BeanDefinitionRegistryPostProcessors

            // 第二步: 调用实现 Ordered 的 BeanDefinitionRegistryPostProcessors。
                // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    // 这时实现了PriorityOrdered.class的postProcessor就不会再被加载进来了, 因为processedBeans.contains(ppName) == true
                    if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                        // 将其放入到currentRegistryProcessors, 马上就要被调用
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                    }
                }
    
                // 对所有的处理器进行排序. 调用了Ordered的方法, 会返回排序(一个数字), 然后根据数字排序即可
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
    
                /**
                 * 第二次调用BeanDefinitionRegistryPostProcessors
                 * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor
                 * 用于进行bean定义的加载 比如我们的包扫描 @import 等
                 */
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();

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

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

    这是第二次调用BeanDefinitionRegistryPostProcessor

    3. 第三次调用BeanDefinitionRegistryPostProcessor

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

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

    4. 第四次调用

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

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

    一共进行了4次调用

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

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

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

    1. ConfigurationClassPostProcessor会调用1234哪几步?
    
    因为ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor,PriorityOrdered, 因此会调用1,4
    
    2. 如果自己定义了一个MyBeanFactoryPostProcessor会调用1234那几步?
    
    package com.lxl.www.iocbeanlifecicle;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    import org.springframework.beans.factory.support.BeanDefinitionRegistry;
    import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
    import org.springframework.beans.factory.support.RootBeanDefinition;
    import org.springframework.stereotype.Component;
    
    @Component
    public class MyBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor {
       @Override
       public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
          
       }
    
       @Override
       public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
       }
    }
    
    
    因为MyBeanFactoryPostProcessor是自定义的, 没有实现任何PriorityOrdered 或者 Order, 因此, 会调用3,4

    二. 详细研究第四步, 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容器中只有一份.

    7. 详细研究四次调用中的第一次调用.  通过分析跟踪@ComponentScan注解是如何解析的,

    通过跟踪@ComponentScan注解是如何解析的, 分来理解BeanDefinitionScan, BeanDefinitionRegistry, BeanDefinitionReader是如何工作的. 

    public static void invokeBeanFactoryPostProcessors(
                ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
            /**
             * 首先,调用BeanDefinitionRegistryPostProcessors 的后置处理器
             * 定义已处理的后置处理器
             */
            // Invoke BeanDefinitionRegistryPostProcessors first, if any.
            Set<String> processedBeans = new HashSet<>();
    
            /**
             * 这里一共分为两大步:
             * 第一步: 调用所有实现了 BeanDefinitionRegistryPostProcessor 接口的bean定义. (BeanDefinitionRegistryPostProcessor带注册功能的后置处理器)
             * 第二步: 调用BeanFactoryPostProcessor Bean工厂的后置处理器
             */
    
            /**********************第一步: 调用所有实现了BeanDefinitionRegistryPostProcessor接口的bean定义  begin****************************/
            // 判断beanFactory是否实现了BeanDefinitionRegistry, 实现了该结构就有注册和获取Bean定义的能力
            if (beanFactory instanceof BeanDefinitionRegistry) {
                BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
                List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
                List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
    
                for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                    if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                        BeanDefinitionRegistryPostProcessor registryProcessor =
                                (BeanDefinitionRegistryPostProcessor) postProcessor;
                        registryProcessor.postProcessBeanDefinitionRegistry(registry);
                        registryProcessors.add(registryProcessor);
                    }
                    else {
                        regularPostProcessors.add(postProcessor);
                    }
                }
    
                // Do not initialize FactoryBeans here: We need to leave all regular beans
                // uninitialized to let the bean factory post-processors apply to them!
                // Separate between BeanDefinitionRegistryPostProcessors that implement
                // PriorityOrdered, Ordered, and the rest.
                /**
                 * 这是一个集合, 存马上即将要被调用的BeanDefinitionRegistryPostProcessor
                 */
                List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
                // 首先, 调用实现了PriorityOrdered的BeanDefinitionRegistryPostProcessors
                // 在所有创世纪的后置处理器中, 只有 internalConfigurationAnnotationProcessor 实现了 BeanDefinitionRegistryPostProcessors 和 PriorityOrdered
                // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
                String[] postProcessorNames =
                        beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    // 判断beanFactory是否实现了PriorityOrdered接口. 如果实现了,是最优先调用.
                    // 在整个加载过程中,会调用四次BeanDefinitionRegistryPostProcessor, 而实现了PriorityOrdered的接口最先调用
                    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                        // 调用beanFactory.getBean实例化配置类的后置处理器(创世界的类ppName), 也就是初始化, 实例化, 赋值属性.
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                    }
                }
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                /**
                 * 第一次调用BeanDefinitionRegistryPostProcessors
                 * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor
                 * 用于进行bean定义的加载 比如我们的包扫描 @import 等
                 */
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                // 处理完了,清空currentRegistryProcessors
                currentRegistryProcessors.clear();

    这里也有两大步

    第一步: 初始化bean工厂的后置处理器

      通过调用beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class) 初始化了bean工厂的后置处理器,

    第二步: 解析配置

       调用invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);调用beanDefinitionRegistry的后置处理器. 筛选出符合条件的配置类. 

    如上图所示, 最后筛选出的配置类只有MainConfig配置类. 也就是说configCandidates配置候选集合中只有一个MainConfig

          // 创建一个ConfigurationClassParser对象, 解析@Configuration class
            ConfigurationClassParser parser = new ConfigurationClassParser(
                    this.metadataReaderFactory, this.problemReporter, this.environment,
                    this.resourceLoader, this.componentScanBeanNameGenerator, registry);
    
            Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
            Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
            do {
                // 执行解析
                parser.parse(candidates);
                parser.validate();

    然后, 接下来创建了一个对象ConfigurationClassParser, 这是一个配置类解析器. 下面将使用这个解析器解析配置类.

    重点是如何解析的, 代码已重点标注出来了.

     // 执行解析
    parser.parse(candidates);

    我们这里是通过注解解析的, 所以直接看下面的代码

    public void parse(Set<BeanDefinitionHolder> configCandidates) {
            // 循环配置类
            for (BeanDefinitionHolder holder : configCandidates) {
                BeanDefinition bd = holder.getBeanDefinition();
                try {
                    // 真正的解析bean定义:通过注解元数据解析
                    if (bd instanceof AnnotatedBeanDefinition) {
                        parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
                    }
    ......
    }

    解析主要做了几件事呢?如下图:

     解析配置类, 看看配置类是否含有如上标记的注解, 如果有, 则调用响应的返回对其进行解析,处理.

    下面来看看源码. 是如何处理这一块的.

    /**
         * 在这里会解析@Component  @PropertySources @ComponentScan @ImportResource
         * @param configClass
         * @param sourceClass
         * @param filter
         * @return
         * @throws IOException
         */
        @Nullable
        protected final SourceClass doProcessConfigurationClass(
                ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
                throws IOException {
    
            // 1. 处理@Component注解,判断元数据是否带有Component注解
            if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
                // Recursively process any member (nested) classes first
                processMemberClasses(configClass, sourceClass, filter);
            }
    
            // Process any @PropertySource annotations
            // 2. 处理@PropertySource 注解, 判断元数据是否带有@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
            // 3. 处理@ComponentScan注解, 判断元数据是否带有@ComponentScan注解
            /**
             * 这里mainConfig配置类中有两个注解,一个是@Configuration ,一个是@ComponentScan. 在这里, 我们看一下@ComponentScan
             */
            //componentScans 拿到的就是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
                    // 解析扫描出来的类, 将其解析为BeanDefinitionHolder对象, 并放入到scannedBeanDefinitions中
                    // 这正的解析ComponentScans和ComponentScan中的配置
                    Set<BeanDefinitionHolder> scannedBeanDefinitions =
                            this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
                    // 循环处理包扫描出来的bean定义
                    // 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());
                        }
                    }
                }
            }
    
            // 4. 处理@Import注解
            // Process any @Import annotations
            processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
    
            // 5. 处理@ImportResource注解
            // Process any @ImportResource annotations
            AnnotationAttributes importResource =
                    AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
            if (importResource != null) {
                String[] resources = importResource.getStringArray("locations");
                Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
                for (String resource : resources) {
                    String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
                    configClass.addImportedResource(resolvedResource, readerClass);
                }
            }
    
            // 6. 处理@Bean注解
            // Process individual @Bean methods
            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;
        }

    下面我们重点看对@ComponentScan和@ComponentScans注解的解析, 为什么看他呢? 因为很多注解都标记了@Component注解. 

    比如@Service注解,本身使用@Component

     再来看@Controller注解, 其实质也是一个@Component注解

     我们在自定义配置类的时候, 会使用@ComponentScan注解. 并传递一个包, 作为扫描包. 如MainConfig配置

     这就会扫描包下所有的配置类. 

    它主要的逻辑如下:

     在拿到@ComponentScan注解以后, 会对其进行parse. 主要解析里面的注解. 并对每一个注解进行处理. 处理后将其添加到scanner属性中. 最后调用scanner.doScan(....)方法.

    源码如下:

    // 解析配置
        public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
            // 定义了一个类路径扫描器ClassPathBeanDefinitionScanner
            // 这里的scanner用于读取配置类
            ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
                    componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
    
            // 1. 判断是否有nameGenerator注解
            // 为扫描器设置beanName的生成器对象, 并赋值给scanner, BeanNameGenerator的作用是为bean definitions生成Bean名字的接口
            Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
            boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
            scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
                    BeanUtils.instantiateClass(generatorClass));
    
            // 2. 判断是否有scopedProxy注解
            ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
            if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
                scanner.setScopedProxyMode(scopedProxyMode);
            }
            else {
                Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
                scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
            }
    
            scanner.setResourcePattern(componentScan.getString("resourcePattern"));
    
            // 3. 判断属性中是否有includeFilters属性, 有的话就添加到scanner中
            // 设置componentScan中包含的过滤器 -- 在使用注解的时候配置了包含和排除的过滤器, 这里进行处理
            for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
                for (TypeFilter typeFilter : typeFiltersFor(filter)) {
                    scanner.addIncludeFilter(typeFilter);
                }
            }
    
            // 4. 判断属性总是否有excludeFilters属性, 有的话放到scnanner中
            // 设置componentScan中排除的过滤器
            for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
                for (TypeFilter typeFilter : typeFiltersFor(filter)) {
                    scanner.addExcludeFilter(typeFilter);
                }
            }
    
            // 5. 判断是否有lazyInit属性
            // 获取配置类中懒加载初始化的属性
            boolean lazyInit = componentScan.getBoolean("lazyInit");
            if (lazyInit) {
                scanner.getBeanDefinitionDefaults().setLazyInit(true);
            }
    
            Set<String> basePackages = new LinkedHashSet<>();
    
            // 6. 判断是否有basePackages属性
            // 获取basePackages属性, 也就是我们定义的包扫描路径
            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);
            }
            for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
                basePackages.add(ClassUtils.getPackageName(clazz));
            }
            if (basePackages.isEmpty()) {
                basePackages.add(ClassUtils.getPackageName(declaringClass));
            }
    
            scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
                @Override
                protected boolean matchClassName(String className) {
                    return declaringClass.equals(className);
                }
            });
    
            // 调用scanner.doScan()方法, 扫描basePackages包
            return scanner.doScan(StringUtils.toStringArray(basePackages));
        }

    调用doScan方法扫描配置类. 我们来看看主要做了哪些事情

     第一步: 找到所有候选的BeanDefinition.

      上面解析出了@ComponentScan注解传递过来的basePackages包. 扫描包中所有的类, 得到候选类. 

      扫描的时候做了几件事呢? 看最上图最右侧部分. 这扫描出来就是我们的目标类.

     第二步: 解析这些准目标类. 

    第三步: 设置默认的beanDefinition属性

    /**
         * 设置默认的bean定义的信息
         * Apply the provided default values to this bean.
         * @param defaults the default settings to apply
         * @since 2.5
         */
        public void applyDefaults(BeanDefinitionDefaults defaults) {
            // 设置这个类是不是懒加载的
            Boolean lazyInit = defaults.getLazyInit();
            if (lazyInit != null) {
                setLazyInit(lazyInit);
            }
            // 设置默认的自动装配方式
            setAutowireMode(defaults.getAutowireMode());
            setDependencyCheck(defaults.getDependencyCheck());
            // 设置初始化方法的名称
            setInitMethodName(defaults.getInitMethodName());
            // 是否可以调用InitMethod方法
            setEnforceInitMethod(false);
            setDestroyMethodName(defaults.getDestroyMethodName());
            // 是否可以调用DestroyMethod方法
            setEnforceDestroyMethod(false);
        }

     第四步: 将解析出来的bean定义注册到ioc容器中

     这里就调用了BeanDefinitionReaderUtils.registerBeanDefinition注册bean定义. 之前注册过配置类, 这里和其是一样的. 所以不再赘述了

    这里有两个细节:

    1. excludeFilter中排除了自己

    public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
            // 定义了一个类路径扫描器ClassPathBeanDefinitionScanner
            // 这里的scanner用于读取配置类
            ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
                    componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
    
            // 1. 判断是否有nameGenerator注解
            // 为扫描器设置beanName的生成器对象
            Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
            boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
            scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
                    BeanUtils.instantiateClass(generatorClass));
    
            // 2. 判断是否有scopedProxy注解
            ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
            if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
                scanner.setScopedProxyMode(scopedProxyMode);
            }
            else {
                Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
                scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
            }
    
            scanner.setResourcePattern(componentScan.getString("resourcePattern"));
    
            // 3. 判断属性中是否有includeFilters属性, 有的话就添加到scanner中
            // 设置componentScan中包含的过滤器 -- 在使用注解的时候配置了包含和排除的过滤器, 这里进行处理
            for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
                for (TypeFilter typeFilter : typeFiltersFor(filter)) {
                    scanner.addIncludeFilter(typeFilter);
                }
            }
    
            // 4. 判断属性总是否有excludeFilters属性, 有的话放到scnanner中
            // 设置componentScan中排除的过滤器
            for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
                for (TypeFilter typeFilter : typeFiltersFor(filter)) {
                    scanner.addExcludeFilter(typeFilter);
                }
            }
    
            // 5. 判断是否有lazyInit属性
            // 获取配置类中懒加载初始化的属性
            boolean lazyInit = componentScan.getBoolean("lazyInit");
            if (lazyInit) {
                scanner.getBeanDefinitionDefaults().setLazyInit(true);
            }
    
            Set<String> basePackages = new LinkedHashSet<>();
    
            // 6. 判断是否有basePackages属性
            // 获取basePackages属性, 也就是我们定义的包扫描路径
            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);
            }
            for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
                basePackages.add(ClassUtils.getPackageName(clazz));
            }
            if (basePackages.isEmpty()) {
                basePackages.add(ClassUtils.getPackageName(declaringClass));
            }
    
            // 想ExcludeFilter中添加默认的排除类,
            scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
                @Override
                protected boolean matchClassName(String className) {
                    /**
                     * declaringClass就是配置类MainConfig, 也就是说. 如果当前类是配置类, 那么就会排除掉
                     * 这是一个钩子方法, 现在不会调用. 后面才调用
                     * 在哪里调用呢?
                      */
                    return declaringClass.equals(className);
                }
            });
    
            // 调用scanner.doScan()方法, 扫描basePackages包
            return scanner.doScan(StringUtils.toStringArray(basePackages));
        }

    在解析配置类的时候, 除了@ComponentScan注解中定义的ExcludeFilter和IncludeFilter以外, 还有默认的排除类. 如上加粗字体的部分. 这里是排除了配置类本身, 我们这里的配置类是MainConfig, 也就说, 会排除掉自己. 

           @Override
                protected boolean matchClassName(String className) {
                    /**
                     * declaringClass就是配置类MainConfig, 也就是说. 如果当前类是配置类, 那么就会排除掉
                     * 这是一个钩子方法, 现在不会调用. 后面才调用
                     * 在哪里调用呢? 先记住这个钩子方法matchClassName
                      */
                    return declaringClass.equals(className);
                }

    matchClassName是一个钩子方法. 在执行到这里的时候, 不会真的去执行. 什么时候执行呢? 后面调用doScan的时候执行.

    protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
            Assert.notEmpty(basePackages, "At least one base package must be specified");
            Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
            // 循环包路径
            for (String basePackage : basePackages) {
                // 第一步: 找到所有候选的BeanDefinition
                /**
                 * 在候选的配置类中, 排除掉了自己, 同时包含了默认的配置类
                 */
                Set<BeanDefinition> candidates = findCandidateComponents(basePackage);

    在寻找候选配置类的时候, 进行了排除了配置类本身.

    public Set<BeanDefinition> findCandidateComponents(String basePackage) {
            if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
                return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
            }
            else {
                // 扫描basePackages, 获取候选类
                return scanCandidateComponents(basePackage);
            }
        }

    进入这个方法

    private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
            Set<BeanDefinition> candidates = new LinkedHashSet<>();
            try {
                //第一步:  将com.lxl.www.iocbeanlifecicle转换成了物理路径com/lxl/www/iocbeanlifecicle
                String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
                        resolveBasePackage(basePackage) + '/' + this.resourcePattern;
                //第二步:  .getResources(...)读取到了包下所有的类
                Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
                boolean traceEnabled = logger.isTraceEnabled();
                boolean debugEnabled = logger.isDebugEnabled();
                for (Resource resource : resources) {
                    if (traceEnabled) {
                        logger.trace("Scanning " + resource);
                    }
                    //第三步:  判断这个类是否是可读的?
                    if (resource.isReadable()) {
                        try {
                            MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
                            //第四步:  判断这个类是否是我们要排除的 或者 包含的
                            if (isCandidateComponent(metadataReader)) {
                                // 通过scnner扫描出来的beanDefinition是ScannedGenericBeanDefinition类型
                                ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
                                // 设置sbd的原类路径
                                sbd.setSource(resource);

    在第四步的时候调用了isCandidateComponent(metadataReader, 这里就判断了是否是包含的类,或者是排除的类

    protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
            // 判断这个类类是否是我们设置的要排除的?
            // 这里依然使用到了策略设计模式. TypeFilter是一个父类, 不同子类的TypeFilter会调用不同的match方法
            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;
        }

    紫色加错的部分是就是判读是否符合排除的类. 红色加错的部分是判断是否是包含的类. 

    先来看紫色的部分, 排除的类

    @Override
        public boolean  match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
                throws IOException {
    
            // This method optimizes avoiding unnecessary creation of ClassReaders
            // as well as visiting over those readers.
            if (matchSelf(metadataReader)) {
                return true;
            }
            ClassMetadata metadata = metadataReader.getClassMetadata();
            // 排除配置类.
            if (matchClassName(metadata.getClassName())) {
                return true;
            }

    看到了么, 这里调用了matchClassName. 这就是上面定义的钩子方法, 

            @Override
                protected boolean matchClassName(String className) {
                    /**
                     * declaringClass就是配置类MainConfig, 也就是说. 如果当前类是配置类, 那么就会排除掉
                     * 这是一个钩子方法, 现在不会调用. 后面才调用
                     * 在哪里调用呢? 先记住这个钩子方法matchClassName
                      */
                    return declaringClass.equals(className);
                }

    此时declaringClass表示的是当前的配置类, className表示的是目标类, 如果当前目标类 == 配置类, 那么就放回true. 返回true, 则会排除掉

    2. includeFilter中包含了默认的配置类

    下面来看红色加错的部分

    protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
            // 判断这个类类是否是我们设置的要排除的?
            // 这里依然使用到了策略设计模式. TypeFilter是一个父类, 不同子类的TypeFilter会调用不同的match方法
            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;
        }

    我们看到这里有this.includeFilters.包含的过滤器. 这里面是有值的

     我们没有在配置类MainConfig上设置includeFilter啊, 这里面怎么会有值呢?

    这是因为我们有默认包含的过滤器, 下面看看默认包含的过滤器是在哪里设置的.

    首先从入口类点击AnnotationConfigApplicationContext

    然后在点击this();

     

    再点击ClassPathBeanDefinitionScanner

     然后一路点击三个this(...)

     最后看到上图 registerDefaultFilter();注册默认的过滤器

    @SuppressWarnings("unchecked")
        protected void registerDefaultFilters() {
            // 注册默认的filter---第一个: 在includeFilter中增加了Component
            this.includeFilters.add(new AnnotationTypeFilter(Component.class));
            ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
            try {
                // 注册默认的filter---第二个:在includeFilter中增加了 javax.annotation.ManagedBean
                this.includeFilters.add(new AnnotationTypeFilter(
                        ((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
                logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
            }
            catch (ClassNotFoundException ex) {
                // JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
            }
            try {
                // 注册默认的filter---第三个:在includeFilter中增加了 javax.inject.Named
                this.includeFilters.add(new AnnotationTypeFilter(
                        ((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
                logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
            }
            catch (ClassNotFoundException ex) {
                // JSR-330 API not available - simply skip.
            }
        }

    如上图看到, 注册了3个默认的过滤器. 分别是Component, ManagedBean, Named. 他们都是注解类型的过滤器AnnotationTypeFilter

    其中javax.annotation.ManagedBean和javax.inject.Named是jdk提供给我们的.

    到此为止, 就将MainConfig配置类解析完并注册到ioc容器中了.

  • 相关阅读:
    LocalDateTime和Date使用@JsonFormat显示毫秒时间
    curl查看ip的几种方式
    thinkphp5.1生成缩略图很模糊
    ajax发送时禁用按钮
    thinkphp5 不使用form,用input+ajax异步上传图片
    GOLANG 闭包和普通函数的区别
    GOLANG 匿名函数笔记
    父级自适应自己高度且高度完全一致css
    子元素等高 css
    ios 用jquery为元素标签绑定点击事件时,ios上不执行点击事件
  • 原文地址:https://www.cnblogs.com/ITPower/p/13913856.html
Copyright © 2020-2023  润新知