zoukankan      html  css  js  c++  java
  • 2.3 spring5源码---spring加载配置类的源码

     

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

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

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

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

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

    第二件事: 调用register(..)

    第三件事: refresh(..) 这里包含了整个ioc创建bean的全生命周期

    二. 自定义配置类

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

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

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

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

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

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

    始终不要忘记我们的整体架构图. 对照这个图来分析. 思路更清晰. 整体内容讲解在这里: 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个原始bean, 这些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);
            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中了

     

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

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

    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

    四. 读取自定义配置类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中. 

    到这里位置我们完成了两步.

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

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

    /**
         * refresh是spring最核心的方法, 里面包含了整个spring ioc的全过程, 包括spring加载bean到销毁bean的全过程
         * 学习spring, 就是学习里面的13个方法, 如果13个方法都学完了, 基本上就打通了
         * @throws BeansException
         * @throws IllegalStateException
         */
        @Override
        public void refresh() throws BeansException, IllegalStateException {
            synchronized (this.startupShutdownMonitor) {
                // 1. 准备刷新上下文环境
                prepareRefresh();
    
                // Tell the subclass to refresh the internal bean factory.
                //2. 获取告诉子类初始化bean工厂, 不同工厂不同实现
                ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
    
                // Prepare the bean factory for use in this context.
                //3. 对bean工厂进行填充属性
                prepareBeanFactory(beanFactory);
    
                try {
                    // Allows post-processing of the bean factory in context subclasses.
                    // 4. 留个子类去实现该接口
                    postProcessBeanFactory(beanFactory);
    
                    // Invoke factory processors registered as beans in the context.
                    /*
                     *
                     * 调用bean工厂的后置处理器
                     * 我们之前在Reader的时候读取了很多创世纪的PostProcessor后置处理器.
                     * 这里要调用bean工厂的后置处理器. 这么多创世纪的PostProcessor, 只有一个PostProcessor实现了
                     * BeanFactoryPostProcessor. 那个类就是 ConfigurationClassPostProcessor
                     * 前面已经将ConfigurationClassPostProcessor放入到BeanDefinitionMap中了,
                     * 对应的BeanDefinitionName 是 internalConfigurationAnnotationProcessor
                     *
                     *
                     *
                     */
                    invokeBeanFactoryPostProcessors(beanFactory);
    
                    // Register bean processors that intercept bean creation.
                    // 注册bean后置处理器
                    registerBeanPostProcessors(beanFactory);
    
                    // Initialize message source for this context.
                    // 初始化国际化资源处理器
                    initMessageSource();
    
                    // Initialize event multicaster for this context.
                    // 创建事件多播放器
                    initApplicationEventMulticaster();
    
                    // Initialize other special beans in specific context subclasses.
                    // 这个方法通用也是留个子类实现的, spring boot也是从这个方法进行启动
                    onRefresh();
    
                    // Check for listener beans and register them.
                    // 将事件监听器注册到多播放器上
                    registerListeners();
    
                    // Instantiate all remaining (non-lazy-init) singletons.
                    // 实例化剩余的单实例bean
                    /**
                     * 这个方法就是循环遍历BeanDefinitionMap, 调用getBean, 去生产bean
                     */
                    finishBeanFactoryInitialization(beanFactory);
    
                    // Last step: publish corresponding event.
                    //最后容器刷新 发布刷新时间(spring cloud是从这里启动的 )
                    finishRefresh();
                }
    
                ........
        }

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

     

     这里调用的时候, 原生处理器只会调用ConfigurationClassPostProcessor.

    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
            /**
             * 获取两处存储BeanFactoryPostProcessor的对象, 传入供接下来调用
             * 1. 当前bean工厂
             * 2. 和我们自己调用addBeanFacoryPostProcessor自定义BeanFactoryPostProcessor
             *
             * 参数: getBeanFactoryPostProcessors() 传了一个工厂的后置处理器的List, 这个时候list是空的
             * getBeanFactoryPostProcessors()里面的值是怎么来的呢?
             * 通过在自定义main方法中调用context.addBeanFactoryPostProcessor(...);来添加
             *
             * public static void main(String[] args) {
             *         // 第一步: 通过AnnotationConfigApplicationContext读取一个配置类
             *         AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
             *         context.addBeanFactoryPostProcessor(...);
             *         Car car = (Car) context.getBean("car");
             *         System.out.println(car.getName());
             *         context.close();
             * }
             */
            PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    
            // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
            // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
            if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
                beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
                beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
            }
        }

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

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

      public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
           return this.beanFactoryPostProcessors;
       }
    getBeanFactoryPostProcessors() 返回的是一个工厂的后置处理器的List, 这个时候list是空的
    getBeanFactoryPostProcessors()里面的值是怎么来的呢?
    通过在自定义main方法中调用context.addBeanFactoryPostProcessor(...);来添加. 也就是通过main 方法手动添加的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只有一个值, 接下来, 判断, 这个类是否实现了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, 调用的是

    一共进行了4次调用

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

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

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

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

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

    先说它, 因为他的概念简单一点

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

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

    full是怎么来的呢?

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

    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");

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

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

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

     

    as

  • 相关阅读:
    算法第五章作业
    第四章实验报告
    算法第三章作业
    算法第三章上机实验报告
    算法第二章作业
    算法第二章上机实践报告
    算法 代码规范(C++)&《数学之美》读后感
    第七章学习小结
    第六章学习小结
    第五章学习小结
  • 原文地址:https://www.cnblogs.com/ITPower/p/13750290.html
Copyright © 2011-2022 走看看