spring之context.refresh详解1

refresh方法详解

本篇文章在上篇文章spring之初始化上下文环境基础上进行继续的源码的解读

源码概览

    /**
     * 启动的根本方法  在里面进行上下文环境的刷新  并发布启动完成事件
     *
     * @throws BeansException
     * @throws IllegalStateException
     */
    @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            //准备刷新  比较简单  设置启动状态,启动时间,初始化一些资源
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            //获得 beanFactory
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            //准备工厂  向工厂中添加一些后置处理器,添加要忽略注入的类型,注释时要替换的类型 环境相关的bean
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                //需要子类实现的方法
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                //调用工厂中所有的 BeanFactoryPostProcessors 一般有我门自定义的(实现接口 )和 spring 内部提供的(如在构造方法中加入的 ConfigurationClassPostProcessor  )
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                //向工厂中加入beanPostProcessor的后置处理器的实例
                //前边几步  有直接向工厂的后置处理器列表中加入的数据  还有向BDMap中加的属性 这时需要获取属性中的定义实例化出来放入到列表中
                registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                //国际化相关
                initMessageSource();

                // Initialize event multicaster for this context.
                //初始化广播器
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                //子类特殊实现的方法  比如SpringBoot中 在此方法完成的Tomcat的启动和 和servlet的绑定
                onRefresh();

                // Check for listener beans and register them.
                //注册监听器
                //发布早期事件
                registerListeners();
                // Instantiate all remaining (non-lazy-init) singletons.
                //实例化 非懒加载的剩余的单例bean
                finishBeanFactoryInitialization(beanFactory);
                // Last step: publish corresponding event.
                //环境刷新完成 做一些后续的处理
                //事件发布
                finishRefresh();
            } catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }

                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();

                // Reset 'active' flag.
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            } finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }
    }

由于refresh方法为spring初始化的核心方法,设计的点比较多如(处理beanFactoryPostProcesson和finishBeanFactoryInitialization)所以这个方法会分开两部步分来讲
方法上已经加了简单注释 按照代码步骤来讲解 比较简单的方法不会展开叙述

第一步 prepareRefresh
  • 准备刷新时的环境,方法比较简单
第二步 obtainFreshBeanFactory
  • 获取 beanFactory 有上一篇文章可以知道获取的是DefaultListableBeanFactory
第三步 prepareBeanFactory
  • 对BeanFactory做一些预处理
/**
     * Configure the factory's standard context characteristics,
     * such as the context's ClassLoader and post-processors.
     *
     * @param beanFactory the BeanFactory to configure
     */
    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // Tell the internal bean factory to use the context's class loader etc.
        //设置 classLoader
        beanFactory.setBeanClassLoader(getClassLoader());
        //bean表达式解析器
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        //设置属性解析器  如字符串转换成class 
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

        // Configure the bean factory with context callbacks.
        //设置回调函数  比如实现了 ApplicationContextAware 就可以获得 ApplicationContext  还有一些其他的回调函数
        //这个是一个后置处理器 现在只是添加到了 dBeanPostProcessor 这个集合中 还没有使用 会在创建bean的时候执行 
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        
        //设置忽略依赖的接口  我们在spring通过 @Resource EnvironmentAware 获取不到
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
        beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

        // BeanFactory interface not registered as resolvable type in a plain factory.
        // MessageSource registered (and found for autowiring) as a bean.
        //设置依赖的替换 获取 @Resource BeanFactory 返回 beanFactory对象
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);

        // Register early post-processor for detecting inner beans as ApplicationListeners.
        //此处又向 BeanPostProcessor 添加了后置处理器
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

        // Detect a LoadTimeWeaver and prepare for weaving, if found.
        if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            //此处向 BeanPostProcessor 添加后置处理器 LoadTimeWeaverAwareProcessor
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            // Set a temporary ClassLoader for type matching.
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

        // Register default environment beans.
        //向容器中添加单例bean  environment  我们可以通过@Resource 获取
        if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
            beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
        }
        //向容器中添加单例bean  systemProperties  我们可以通过@Resource 获取
        if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
            beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
        }
        //向容器中添加单例bean  systemEnvironment  我们可以通过@Resource 获取
        if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
            beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
        }
    }

beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); 这行代码的作用就是处理aware回调让我们可以获取一些spring内部的属性如EnvironmentAwareApplicationContextAwareApplicationEventPublisherAware

注意当前方法只是向BeanPostProcessor这个集合中添加了对象但是这些后置处理器还没有起作用,后置处理器的作用时间是bean创建前后

第四步 postProcessBeanFactory
  • 是一个空方法,留着子类实现,当前类没有实现
第五步 invokeBeanFactoryPostProcessors
  • 执行beanFactory的后置处理器可以是我们自定义的实现了BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor 这两个接口的类或者是spring内部提供的。看过第一篇文章的同学不知道还有没有印象我们在实例化AnnotatedBeanDefinitionReader对象的时候在内部是向bdMap中添加了几个后置处理器其中就有一个ConfigurationClassPostProcessor类。

  • ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessorBeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor它所有ConfigurationClassPostProcessor是一个工厂的后置处理器。这里调用postProcessBeanFactory方法实际上就是执行bean工厂后置处理器的方法

代码如下

  • 请注意看代码方法的注释,第二个参数的含义一般来说这个集合是为空的,因为我们不会手动的通过new的方式添加
  • 方法很长会在一些主要的方法上做注释,需要详解的点下边会再进行详细的解读
/**
     * 调用所有的工厂的后置处理器和它的实现类
     *
     * @param beanFactory
     * @param beanFactoryPostProcessors 这个参数  是由我门开发人员手动添加的  (此处的手动添加的含义是  我们实现的接口
     *                                  但是不用注解扫描获得而是直接调用context.add(new Impl()) 直接new的方式)一般不会有
     */
    public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

        // 第一步首先调用所有的  BeanFactoryPostProcessor 的实现类 BeanDefinitionRegistryPostProcessors 的方法
        // Invoke BeanDefinitionRegistryPostProcessors first, if any.
        //此处是定义一个可以去重的集合 下边会根据在集合中存不存在来判断有没有被解析过  防止再执行后置处理器时又有新添加的后置处理器需要处理
        Set<String> processedBeans = new HashSet<>();
        //beanFactory 实际是一个大的注册中心  实例化时可以看继承关系
        if (beanFactory instanceof BeanDefinitionRegistry) {
            //获取注册中心
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            //我们自己new出来的 实现了 BeanFactoryPostProcessor 的 后置处理期
            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
            //我们自己new出来的 实现了 BeanDefinitionRegistryPostProcessor 的后置处理器
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

            //遍历自己new出来的 放入到上边定义的集合中
            //如果是子类 BeanDefinitionRegistryPostProcessor   则执行子类特有的方法
            //此逻辑一般不会进  我们不会这样去添加
            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.、

            // spring内部提供的  或者是我们自定义的但是依赖spring实例化的  不是 new 的方式添加的
            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

            // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
            //根据类型获取所有的实现了 BeanDefinitionRegistryPostProcessors 的后置处理器
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                //实现了 PriorityOrdered 这个接口 代表高优先级 先处理
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    //向 list中添加 实现类
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    //添加到用于判重的集合
                    processedBeans.add(ppName);
                }
            }
            //排序
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            //集合的累加 添加到上边定义的村方 new出来的后置处理器
            registryProcessors.addAll(currentRegistryProcessors);
            //到此处 如果我们手动添加的话 一般只会有一个  ConfigurationClassPostProcessor 实在 创建 AnnotatedBeanDefinitionReader 时添加的
            //调用 org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            //清空当前实现了BeanDefinitionRegistryPostProcessor 和 PriorityOrdered  集合
            currentRegistryProcessors.clear();

            // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
            //获取所有实现了 BeanDefinitionRegistryPostProcessor 接口的实现类 
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 判断上边没有处理过 并且实现了 Ordered 接口 
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    //添加到 自定义集合中 
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    //添加到 已处理的集合中
                    processedBeans.add(ppName);
                }
            }
            //排序  
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            //添加到 registryProcessors 集合中 这个结合中还存放了上边 实现了 PriorityOrdered 接口的 类但是只是执行了 postProcessBeanDefinitionRegistry 方法的后置处理器
            registryProcessors.addAll(currentRegistryProcessors);
            //执行 currentRegistryProcessors 中 所有的 后置处理器的  postProcessBeanDefinitionRegistry 方法 
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            //清空
            currentRegistryProcessors.clear();

            // 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) {
                    if (!processedBeans.contains(ppName)) {
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                        reiterate = true;
                    }
                }
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();
            }

            // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
            //调用父类的方法 当前这个集合 中还有 BeanDefinitionRegistryPostProcessor 它在上边只是调用了自己的方法 还没有调用父类的方法
            //这一步 对全配置类很重要  对全配置类做了 cglib 增强 修改了bd中类的class类型 在创建的时候会创建代理对象
            //org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanFactory
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            //调用我们自己new出来的 实现了 BeanFactoryPostProcessor 接口的 postProcessBeanFactory 方法
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        } else {
            // Invoke factory processors registered with the context instance.
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }

        // Do not initialize FactoryBeans here: We need to leave all regular beans
        // uninitialized to let the bean factory post-processors apply to them!
        //根据类型获取所有的名字
        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);
            }
        }

        //========================此处一般不会有 不需要重点关注 是spring做的严谨=======================================

        // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
        //排序
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        //执行高优先级队列  一般不会有
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
        for (String postProcessorName : orderedPostProcessorNames) {
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
        //执行低优先级队 类  一般不会有
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

        // Finally, invoke all other BeanFactoryPostProcessors.
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
        for (String postProcessorName : nonOrderedPostProcessorNames) {
            nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        //普通的  一般不会有
        invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

        //=========================================================================
        // Clear cached merged bean definitions since the post-processors might have
        // modified the original metadata, e.g. replacing placeholders in values...
        beanFactory.clearMetadataCache();
    }

从上边的方法中可以看出主要的逻辑就是执行 BeanFactoryPostProcessor#postProcessBeanFactory 方法 和 BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry方法由于我们没有向容器中添加这两个接口的实现类那么就分析spring内部提供ConfigurationClassPostProcessor

ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
  • 该方法的主要作用是解析配置类把扫描出来的bean转成bd放入到bdMap中
  • 标注配置类是全注解类还是非全注解类即加没加@Configuration注解
    /**
     * Build and validate a configuration model based on the registry of
     * {@link Configuration} classes.
     */
    public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
        //存储需要处理的配置的 BeanDefinitionHolder 就是 BeanDefinition 和  beanName
        List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
        //获取所有需要通过工厂实例化的bean的名称 一般来说当前只有一些后置处理器的名称
        String[] candidateNames = registry.getBeanDefinitionNames();

        for (String beanName : candidateNames) {
            //根据名称获取bean的定义信息
            BeanDefinition beanDef = registry.getBeanDefinition(beanName);
            //判断 当前的定义信息属性中 是否标注了 是全注解类(FullConfigurationClass) 或者 是非全注解类(iteConfigurationClass)
            //如果是的话证明这个配置类被解析过  因为解析时会修改bean的定义信息设置这个字段的属性
            if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
                    ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
                if (logger.isDebugEnabled()) {
                    //有的话证明已经被解析过
                    logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
                }
                //ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory) 方法中
                //会修改bd的定义信息  如 如果类上有注解@Configuration 则会增加一个是全注解类的标示
                //会获取 Order的值进行设置
                //有兴趣可以点开细看
            } else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
                //添加
                configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
            }
        }

        // Return immediately if no @Configuration classes were found
        //没有全注解配置类  直接返回
        //感觉描述不太准确  为空并不一定是没有@Configuration这个类  非全注解的类也没有
        if (configCandidates.isEmpty()) {
            return;
        }

        //排序
        // Sort by previously determined @Order value, if applicable
        configCandidates.sort((bd1, bd2) -> {
            int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
            int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
            return Integer.compare(i1, i2);
        });

        // Detect any custom bean name generation strategy supplied through the enclosing application context
        SingletonBeanRegistry sbr = null;
        if (registry instanceof SingletonBeanRegistry) {
            sbr = (SingletonBeanRegistry) registry;
            if (!this.localBeanNameGeneratorSet) {
                //获取 名字生成器
                BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
                if (generator != null) {
                    this.componentScanBeanNameGenerator = generator;
                    this.importBeanNameGenerator = generator;
                }
            }
        }

        if (this.environment == null) {
            //初始化一个环境
            this.environment = new StandardEnvironment();
        }

        // Parse each @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 {
            //配置类解析   一部分会直接放入到bdMap中还有一部分没有 
            //主要方法
            //@1
            parser.parse(candidates);
            //验证全注解类 是否可被继承 方法是否可重写
            parser.validate();

            //作为配置类的对象  在里面解析时不会放入到 bdMap中
            Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
            configClasses.removeAll(alreadyParsed);

            // Read the model and create bean definitions based on its content
            if (this.reader == null) {
                this.reader = new ConfigurationClassBeanDefinitionReader(
                        registry, this.sourceExtractor, this.resourceLoader, this.environment,
                        this.importBeanNameGenerator, parser.getImportRegistry());
            }
            //在这读取所有的配置bean的相关定义信息  加入到BdMap中
            //beanMethod  importBdR
            //  在@1解析后会有一些放在集合中  还没有处理   在这一步  把那些需要处理的bd放入到bdMap中
            this.reader.loadBeanDefinitions(configClasses);
            alreadyParsed.addAll(configClasses);

            //清空要处理的注解类
            candidates.clear();

            //是否有在bdMap中但是没有在BDNames中的类
            if (registry.getBeanDefinitionCount() > candidateNames.length) {

                String[] newCandidateNames = registry.getBeanDefinitionNames();
                Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
                Set<String> alreadyParsedClasses = new HashSet<>();
                //找出已经解析过的配置类
                for (ConfigurationClass configurationClass : alreadyParsed) {
                    alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
                }
                for (String candidateName : newCandidateNames) {
                    //第一次没被加载到的配置bean
                    if (!oldCandidateNames.contains(candidateName)) {
                        BeanDefinition bd = registry.getBeanDefinition(candidateName);
                        if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
                                !alreadyParsedClasses.contains(bd.getBeanClassName())) {
                            candidates.add(new BeanDefinitionHolder(bd, candidateName));
                        }
                    }
                }
                candidateNames = newCandidateNames;
            }
        }//循环处理  直到为空
        while (!candidates.isEmpty());

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

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

由于本篇文章的重点是bean的初始化流程。所以对解析配置类暂且略过,后边会有专门的文章补充进来,因为对配置类的解析涉及到的点太多。

说完了ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry本身的方法再来看一下它实现了父类方法做的什么事

ConfigurationClassPostProcessor#postProcessBeanFactory

  • 该方法主要做了一件事 就是对标注了全注解的配置类基于CGLIB的动态代理增强
  • 增强的好处是我们在@Bean 是会创建一个bean 这点会在后边的文章详细描述
    /**
     * 对全注解配置类进行 CGLIB 增强
     * Prepare the Configuration classes for servicing bean requests at runtime
     * by replacing them with CGLIB-enhanced subclasses.
     */
    @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);
        }
        //增强
        enhanceConfigurationClasses(beanFactory);
        //添加解析  ImportAware 注解功能的后置处理器
        beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
    }

enhanceConfigurationClasses方法有兴趣可以先看看,后边再根据我的文章看一下。

到现在为止假设我们没有自己实现beanFactory的后置管理器那么第五部执行后置处理器方法就运行完了。
总结一下:
1.根据配置类解析/扫描把所有的bean转成bd放入到bdMap中
2.为全注解配置类生成CGLIB代理对象

第六步 registerBeanPostProcessors(beanFactory)
  • 把还是bd的bean的后置处理器实例化成bean对象加入到后置处理器集合中,因为后边生成bean的时候会使用
第七步 initMessageSource()
  • 国际化相关处理资源
第八步 initApplicationEventMulticaster()
  • 初始化广播器,我们可以自定义监听器接受相关的事件
第九步 onRefresh()
  • 也是一个空壳方法,依赖子类的实现,典型的例子是springBoot中在这个里面启动了内嵌的容器
第十步 registerListeners()
  • 注册监听器发布相关事件

还有两步会在后边文章讲述
这篇文章主要的点是我们的类是怎么变成bd的
下篇文章是工厂根据bd是怎么创建对象的

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