ConfigurationClassPostProcessor类的processConfigBeanDefinitions方法源码解析

spring版本为5.0.11

ConfigurationClassPostProcessor类处理带有@Configuration配置类,使用方法processConfigBeanDefinitions
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
        //1.初始化BeanDefinitionHolder集合
        List<BeanDefinitionHolder> configCandidates = new ArrayList();
        //2.所有已经注册的bean 
        String[] candidateNames = registry.getBeanDefinitionNames();
        String[] var4 = candidateNames;
        int var5 = candidateNames.length;
        //3.遍历已注册的bean数组
        for(int var6 = 0; var6 < var5; ++var6) {
            //bean名称
            String beanName = var4[var6];
            //得到BeanDefinition实例
            BeanDefinition beanDef = registry.getBeanDefinition(beanName);
            //判断:full configuration 和 lite configuration
            //参照https://www.cnblogs.com/mufeng07/p/12163442.html
            if (!ConfigurationClassUtils.isFullConfigurationClass(beanDef) && !ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
                //带有@Configuration注解的bean,beanDef的属性设置为full,beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, "full");
                if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
                    //带有@Configuration注解的bean添加到集合中
                    configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
                }
            } else if (this.logger.isDebugEnabled()) {
            //两种都不满足,配置类已经被处理了
                this.logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
            }
        }
        //集合非空
        if (!configCandidates.isEmpty()) {
            // 多个Java配置类,按@Ordered注解排序
            configCandidates.sort((bd1, bd2) -> {
                int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
                int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
                return Integer.compare(i1, i2);
            });
            //检测通过封闭的应用程序上下文提供的任何自定义bean名称生成策略
            //暂时不理解
            SingletonBeanRegistry sbr = null;
            if (registry instanceof SingletonBeanRegistry) {
                sbr = (SingletonBeanRegistry)registry;
                if (!this.localBeanNameGeneratorSet) {
                    BeanNameGenerator generator = (BeanNameGenerator)sbr.getSingleton("org.springframework.context.annotation.internalConfigurationBeanNameGenerator");
                    if (generator != null) {
                        this.componentScanBeanNameGenerator = generator;
                        this.importBeanNameGenerator = generator;
                    }
                }
            }
            //web应用为StandardServletEnvironment
            if (this.environment == null) {
                this.environment = new StandardEnvironment();
            }
            //初始化一个ConfigurationClassParser解析器,可以解析@Congiguration配置类
            ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry);
            //List转成Set
            Set<BeanDefinitionHolder> candidates = new LinkedHashSet(configCandidates);
            //初始化一个已经解析的HashSet
            HashSet alreadyParsed = new HashSet(configCandidates.size());
            //循环解析,直到candidates为空
            do {
                //核心:解析
                parser.parse(candidates);
                //主要校验配置类不能使用final修饰符(CGLIB代理是生成一个子类,因此原先的类不能使用final修饰)
                //if (this.getMetadata().isAnnotated(Configuration.class.getName()) && this.getMetadata().isFinal()) 
                parser.validate();
                //排除已处理过的配置类
                Set<ConfigurationClass> configClasses = new LinkedHashSet(parser.getConfigurationClasses());
                configClasses.removeAll(alreadyParsed);
                //读取模型并根据其内容创建bean定义
                if (this.reader == null) {
                    this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry());
                }
                //2.加载bean定义信息,主要实现将@Configuration @Import @ImportResource @ImportRegistrar注册为bean
                this.reader.loadBeanDefinitions(configClasses);
                //将configClasses加入到已解析alreadyParsed中
                alreadyParsed.addAll(configClasses);
                //清空已处理的配置类
                candidates.clear();
                //再次获取容器中bean定义数量  如果大于 之前获取的bean定义数量,则说明有新的bean注册到容器中,需要再次解析
                ///getBeanDefinitionCount()取得是registry.beanDefinitionMap.size()
                if (registry.getBeanDefinitionCount() > candidateNames.length) {
                    //容器中新的所有已注册的bean(包括老的)
                    String[] newCandidateNames = registry.getBeanDefinitionNames();
                    //容器中老的已注册的bean(已经解析了)
                    Set<String> oldCandidateNames = new HashSet(Arrays.asList(candidateNames));
                    //用来存储已经解析的类
                    Set<String> alreadyParsedClasses = new HashSet();
                    Iterator var12 = alreadyParsed.iterator();
                    //循环遍历把已解析的类放到alreadyParsedClasses中
                    while(var12.hasNext()) {
                        ConfigurationClass configurationClass = (ConfigurationClass)var12.next();
                        alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
                    }

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

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

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

        }
    }
核心:如何进行解析ConfigurationClassParser类,parser.parse(candidates)

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {        //1.初始化BeanDefinitionHolder集合List<BeanDefinitionHolder> configCandidates = new ArrayList();//2.所有已经注册的bean         String[] candidateNames = registry.getBeanDefinitionNames();        String[] var4 = candidateNames;        int var5 = candidateNames.length;        //3.遍历已注册的bean数组        for(int var6 = 0; var6 < var5; ++var6) {    //bean名称            String beanName = var4[var6];    //得到BeanDefinition实例            BeanDefinition beanDef = registry.getBeanDefinition(beanName);//判断:full configuration 和 lite configuration//参照https://www.cnblogs.com/mufeng07/p/12163442.html            if (!ConfigurationClassUtils.isFullConfigurationClass(beanDef) && !ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {    //带有@Configuration注解的bean,beanDef的属性设置为full,beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, "full");                if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {    //带有@Configuration注解的bean添加到集合中                    configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));                }            } else if (this.logger.isDebugEnabled()) {//两种都不满足,配置类已经被处理了                this.logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);            }        }        //集合非空        if (!configCandidates.isEmpty()) {    // 多个Java配置类,按@Ordered注解排序            configCandidates.sort((bd1, bd2) -> {                int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());                int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());                return Integer.compare(i1, i2);            });//检测通过封闭的应用程序上下文提供的任何自定义bean名称生成策略//暂时不理解            SingletonBeanRegistry sbr = null;            if (registry instanceof SingletonBeanRegistry) {                sbr = (SingletonBeanRegistry)registry;                if (!this.localBeanNameGeneratorSet) {                    BeanNameGenerator generator = (BeanNameGenerator)sbr.getSingleton("org.springframework.context.annotation.internalConfigurationBeanNameGenerator");                    if (generator != null) {                        this.componentScanBeanNameGenerator = generator;                        this.importBeanNameGenerator = generator;                    }                }            }            //web应用为StandardServletEnvironment            if (this.environment == null) {                this.environment = new StandardEnvironment();            }            //初始化一个ConfigurationClassParser解析器,可以解析@Congiguration配置类            ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry);            //List转成SetSet<BeanDefinitionHolder> candidates = new LinkedHashSet(configCandidates);//初始化一个已经解析的HashSet            HashSet alreadyParsed = new HashSet(configCandidates.size());            //循环解析,直到candidates为空            do {    //核心:解析                parser.parse(candidates);//主要校验配置类不能使用final修饰符(CGLIB代理是生成一个子类,因此原先的类不能使用final修饰)//if (this.getMetadata().isAnnotated(Configuration.class.getName()) && this.getMetadata().isFinal())                 parser.validate();//排除已处理过的配置类                Set<ConfigurationClass> configClasses = new LinkedHashSet(parser.getConfigurationClasses());                configClasses.removeAll(alreadyParsed);//读取模型并根据其内容创建bean定义                if (this.reader == null) {                    this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry());                }                //2.加载bean定义信息,主要实现将@Configuration @Import @ImportResource @ImportRegistrar注册为bean                this.reader.loadBeanDefinitions(configClasses);//将configClasses加入到已解析alreadyParsed中                alreadyParsed.addAll(configClasses);//清空已处理的配置类                candidates.clear();//再次获取容器中bean定义数量  如果大于 之前获取的bean定义数量,则说明有新的bean注册到容器中,需要再次解析///getBeanDefinitionCount()取得是registry.beanDefinitionMap.size()                if (registry.getBeanDefinitionCount() > candidateNames.length) {    //容器中新的所有已注册的bean(包括老的)                    String[] newCandidateNames = registry.getBeanDefinitionNames();//容器中老的已注册的bean(已经解析了)                    Set<String> oldCandidateNames = new HashSet(Arrays.asList(candidateNames));//用来存储已经解析的类                    Set<String> alreadyParsedClasses = new HashSet();                    Iterator var12 = alreadyParsed.iterator();                    //循环遍历把已解析的类放到alreadyParsedClasses中                    while(var12.hasNext()) {                        ConfigurationClass configurationClass = (ConfigurationClass)var12.next();                        alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());                    }
                    String[] var23 = newCandidateNames;                    int var24 = newCandidateNames.length;                    //循环遍历新的所有已注册的bean,排除老的已解析的,再过滤是否是配置类带有@Configuration,并且没有解析过,添加到candidates中,//下一次可以再处理解析                    for(int var14 = 0; var14 < var24; ++var14) {                        String candidateName = var23[var14];                        if (!oldCandidateNames.contains(candidateName)) {                            BeanDefinition bd = registry.getBeanDefinition(candidateName);                            if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) && !alreadyParsedClasses.contains(bd.getBeanClassName())) {                                candidates.add(new BeanDefinitionHolder(bd, candidateName));                            }                        }                    }
                    candidateNames = newCandidateNames;                }            } while(!candidates.isEmpty());            //// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes            if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {                sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());            }
            if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {     // Clear cache in externally provided MetadataReaderFactory; this is a no-op                 // for a shared cache since it‘ll be cleared by the ApplicationContext.                ((CachingMetadataReaderFactory)this.metadataReaderFactory).clearCache();            }
        }    }

相关推荐