ConfigurationClassParser类的parse方法源码解析

spring版本为5.0.11

ConfigurationClassPostProcessor对配置类的解析
public void parse(Set<BeanDefinitionHolder> configCandidates) {
        //List<ConfigurationClassParser.DeferredImportSelectorHolder> deferredImportSelectors 进行初始化 
        this.deferredImportSelectors = new LinkedList();
        Iterator var2 = configCandidates.iterator();
        //循环遍历需要处理的配置类
        while(var2.hasNext()) {
            BeanDefinitionHolder holder = (BeanDefinitionHolder)var2.next();
            BeanDefinition bd = holder.getBeanDefinition();
            //根据BeanDefinition实例判断调用哪个,其实最后还是调用
            //核心方法:processConfigurationClass(ConfigurationClass configClass)
            try {
                if (bd instanceof AnnotatedBeanDefinition) {
                    this.parse(((AnnotatedBeanDefinition)bd).getMetadata(), holder.getBeanName());
                } else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition)bd).hasBeanClass()) {
                    this.parse(((AbstractBeanDefinition)bd).getBeanClass(), holder.getBeanName());
                } else {
                    this.parse(bd.getBeanClassName(), holder.getBeanName());
                }
            } catch (BeanDefinitionStoreException var6) {
                throw var6;
            } catch (Throwable var7) {
                throw new BeanDefinitionStoreException("Failed to parse configuration class [" + bd.getBeanClassName() + "]", var7);
            }
        }
        //字面理解:处理延迟导入的javabean
        //parse方法,把被处理的类实现DeferredImportSelector接口,加入deferredImportSelectors集合中,
        //处理deferredImportSelectors集合种类
        this.processDeferredImportSelectors();
    }

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

protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
        //检查当前解析的配置bean是否包含Conditional注解,如果不包含则不需要跳过
        // 如果包含了则进行match方法得到匹配结果,如果是符合的并且设置的配置解析策略是解析阶段不需要调过
        if (!this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
            //在这里处理Configuration重复import
            //如果同一个配置类被处理两次,两次都属于被import的则合并导入类,返回。如果配置类不是被导入的,则移除旧使用新的配置类
            ConfigurationClass existingClass = (ConfigurationClass)this.configurationClasses.get(configClass);
            if (existingClass != null) {
                if (configClass.isImported()) {
                    if (existingClass.isImported()) {
                        existingClass.mergeImportedBy(configClass);
                    }
                    // Otherwise ignore new imported config class; existing non-imported class overrides it.
                    return;
                }
                // Explicit bean definition found, probably replacing an import.
                // Let's remove the old one and go with the new one.
                this.configurationClasses.remove(configClass);
                this.knownSuperclasses.values().removeIf(configClass::equals);
            }
            // Recursively process the configuration class and its superclass hierarchy.
            ConfigurationClassParser.SourceClass sourceClass = this.asSourceClass(configClass);
            //递归解析
            do {
                sourceClass = this.doProcessConfigurationClass(configClass, sourceClass);
            } while(sourceClass != null);
            // 添加到ConfigurationClassParser的configurationClasses中
            this.configurationClasses.put(configClass, configClass);
        }
    }

递归解析,调用doProcessConfigurationClass方法,终于到了解析的地方!!

总结一下:

1.处理内部类

2.处理@PropertySource注解

3.处理@ComponentScan注解

4.处理@Import注解

5.处理@ImportResource注解

6.处理@Bean修饰的方法

7.处理接口定义的方法

8.处理父类

protected final ConfigurationClassParser.SourceClass doProcessConfigurationClass(ConfigurationClass configClass, ConfigurationClassParser.SourceClass sourceClass) throws IOException {
        // Recursively process any member (nested) classes first 处理内部类
        this.processMemberClasses(configClass, sourceClass);
        // Process any @PropertySource annotations
        // 处理@PropertySource注解
        Iterator var3 = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), PropertySources.class, PropertySource.class).iterator();

        AnnotationAttributes importResource;
        while(var3.hasNext()) {
            importResource = (AnnotationAttributes)var3.next();
            if (this.environment instanceof ConfigurableEnvironment) {
                this.processPropertySource(importResource);
            } else {
                this.logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() + "]. Reason: Environment must implement ConfigurableEnvironment");
            }
        }
        //// Process any @ComponentScan annotations
        // 处理@ComponentScan注解
        Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
        if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
            Iterator var13 = componentScans.iterator();
            // The config class is annotated with @ComponentScan -> perform the scan immediately
            //扫描
            while(var13.hasNext()) {
                AnnotationAttributes componentScan = (AnnotationAttributes)var13.next();
                Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
                Iterator var7 = scannedBeanDefinitions.iterator();
                // Check the set of scanned definitions for any further config classes and parse recursively if necessary
                //遍历扫描到的配置类进行递归解析
                while(var7.hasNext()) {
                    BeanDefinitionHolder holder = (BeanDefinitionHolder)var7.next();
                    BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
                    if (bdCand == null) {
                        bdCand = holder.getBeanDefinition();
                    }

                    if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
                        this.parse(bdCand.getBeanClassName(), holder.getBeanName());
                    }
                }
            }
        }
        // Process any @Import annotations
        // 处理@Import注解
        this.processImports(configClass, sourceClass, this.getImports(sourceClass), true);
        // Process any @ImportResource annotations.
        // 处理@ImportResource 注解
        importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
        if (importResource != null) {
            String[] resources = importResource.getStringArray("locations");
            Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
            String[] var19 = resources;
            int var21 = resources.length;
            // 遍历配置的locations,加入到configClass 中的ImportedResource
            for(int var22 = 0; var22 < var21; ++var22) {
                String resource = var19[var22];
                String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
                configClass.addImportedResource(resolvedResource, readerClass);
            }
        }
        // Process individual @Bean methods
        // 处理@Bean修饰的方法
        Set<MethodMetadata> beanMethods = this.retrieveBeanMethodMetadata(sourceClass);
        Iterator var17 = beanMethods.iterator();

        while(var17.hasNext()) {
            MethodMetadata methodMetadata = (MethodMetadata)var17.next();
            configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
        }
        // Process default methods on interfaces
        // 处理接口定义的方法
        this.processInterfaces(configClass, sourceClass);
        if (sourceClass.getMetadata().hasSuperClass()) {
            String superclass = sourceClass.getMetadata().getSuperClassName();
            if (superclass != null && !superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) {
                this.knownSuperclasses.put(superclass, configClass);
                // Superclass found, return its annotation metadata and recurse
                return sourceClass.getSuperClass();
            }
        }
        // No superclass -> processing is complete
        return null;
    }

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

private void processMemberClasses(ConfigurationClass configClass, ConfigurationClassParser.SourceClass sourceClass) throws IOException {
        //读取配置类中所有成员类
        Collection<ConfigurationClassParser.SourceClass> memberClasses = sourceClass.getMemberClasses();
        if (!memberClasses.isEmpty()) {
            List<ConfigurationClassParser.SourceClass> candidates = new ArrayList(memberClasses.size());
            Iterator var5 = memberClasses.iterator();
            //过滤出配置类
            ConfigurationClassParser.SourceClass candidate;
            while(var5.hasNext()) {
                candidate = (ConfigurationClassParser.SourceClass)var5.next();
                if (ConfigurationClassUtils.isConfigurationCandidate(candidate.getMetadata()) && !candidate.getMetadata().getClassName().equals(configClass.getMetadata().getClassName())) {
                    candidates.add(candidate);
                }
            }
            //根据Order进行排序
            OrderComparator.sort(candidates);
            var5 = candidates.iterator();
            //遍历
            while(var5.hasNext()) {
                candidate = (ConfigurationClassParser.SourceClass)var5.next();
                //1)出现配置类循环导入,直接报错
                if (this.importStack.contains(configClass)) {
                    this.problemReporter.error(new ConfigurationClassParser.CircularImportProblem(configClass, this.importStack));
                } else {
                    //将配置类入栈
                    this.importStack.push(configClass);

                    try {
                        //处理配置类
                        this.processConfigurationClass(candidate.asConfigClass(configClass));
                    } finally {
                        //解析完出栈
                        this.importStack.pop();
                    }
                }
            }
        }

    }

2.处理@PropertySource注解

 如果配置类上有@PropertySource注解,则解析加载properties文件,并将属性添加到Spring上下文中。

this.addPropertySource(factory.createPropertySource(name, new EncodedResource(resource, encoding)));

3.处理@ComponentScan注解

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

// Process any @ComponentScan annotations
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
        if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
            Iterator var13 = componentScans.iterator();

            while(var13.hasNext()) {
                AnnotationAttributes componentScan = (AnnotationAttributes)var13.next();
                // The config class is annotated with @ComponentScan -> perform the scan immediately
                Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
                Iterator var7 = scannedBeanDefinitions.iterator();
                // Check the set of scanned definitions for any further config classes and parse recursively if needed
                while(var7.hasNext()) {
                    BeanDefinitionHolder holder = (BeanDefinitionHolder)var7.next();
                    BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
                    if (bdCand == null) {
                        bdCand = holder.getBeanDefinition();
                    }
                    //检验扫描获得的BeanDefinition中是否有配置类,如果有配置类,这里的配置类包括FullConfigurationClass和LiteConfigurationClass。
                    //(也就是说只要有@Configuration、@Component、@ComponentScan、@Import、@ImportResource和@Bean中的其中一个注解),则递归调用parse方法,进行解析。
                    if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
                        this.parse(bdCand.getBeanClassName(), holder.getBeanName());
                    }
                }
            }
        }

4.处理@Import注解

this.processImports(configClass, sourceClass, this.getImports(sourceClass), true);
processImports方法负责对@Import注解进行解析。configClass是配置类,sourceClass又是通过configClass创建的,getImports(sourceClass)sourceClass获取所有的@Import注解信息
private void processImports(ConfigurationClass configClass, ConfigurationClassParser.SourceClass currentSourceClass, Collection<ConfigurationClassParser.SourceClass> importCandidates, boolean checkForCircularImports) {
        if (!importCandidates.isEmpty()) {
            //循环导入直接报错
            if (checkForCircularImports && this.isChainedImportOnStack(configClass)) {
                this.problemReporter.error(new ConfigurationClassParser.CircularImportProblem(configClass, this.importStack));
            } else {
                //推入栈
                this.importStack.push(configClass);

                try {
                    Iterator var5 = importCandidates.iterator();
                    //循环遍历
                    while(true) {
                        while(true) {
                            while(var5.hasNext()) {
                                ConfigurationClassParser.SourceClass candidate = (ConfigurationClassParser.SourceClass)var5.next();
                                Class candidateClass;
                                //对import的内容进行分类
                                // import导入实现ImportSelector接口的类
                                if (candidate.isAssignable(ImportSelector.class)) {
                                    // Candidate class is an ImportSelector -> delegate to it to determine imports
                                    candidateClass = candidate.loadClass();
                                    // 反射创建这个类的实例对象
                                    ImportSelector selector = (ImportSelector)BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
                                    //是否有实现相关Aware接口,如果有,这调用相关方法
                                    ParserStrategyUtils.invokeAwareMethods(selector, this.environment, this.resourceLoader, this.registry);
                                    // 延迟加载的ImportSelector
                                    if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {
                                        //  延迟加载的ImportSelector先放到List中,延迟加载
                                        this.deferredImportSelectors.add(new ConfigurationClassParser.DeferredImportSelectorHolder(configClass, (DeferredImportSelector)selector));
                                    } else {
                                        // 普通的ImportSelector ,执行其selectImports方法,获取需要导入的类的全限定类名数组
                                        String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
                                        Collection<ConfigurationClassParser.SourceClass> importSourceClasses = this.asSourceClasses(importClassNames);
                                        // 递归调用
                                        this.processImports(configClass, currentSourceClass, importSourceClasses, false);
                                    }
                                    // 是否为ImportBeanDefinitionRegistrar
                                } else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
                                    // Candidate class is an ImportBeanDefinitionRegistrar ->
                                    // delegate to it to register additional bean definitions
                                    candidateClass = candidate.loadClass();
                                    ImportBeanDefinitionRegistrar registrar = (ImportBeanDefinitionRegistrar)BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
                                    ParserStrategyUtils.invokeAwareMethods(registrar, this.environment, this.resourceLoader, this.registry);
                                    // 添加到成员变量
                                    configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
                                } else {
                                    // Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
                                    // process it as an @Configuration class
                                    // 普通 @Configuration class
                                    this.importStack.registerImport(currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
                                    // 解析导入的@Configuration class
                                    this.processConfigurationClass(candidate.asConfigClass(configClass));
                                }
                            }

                            return;
                        }
                    }
                } catch (BeanDefinitionStoreException var15) {
                    throw var15;
                } catch (Throwable var16) {
                    throw new BeanDefinitionStoreException("Failed to process import candidates for configuration class [" + configClass.getMetadata().getClassName() + "]", var16);
                } finally {
                    this.importStack.pop();
                }
            }
        }
    }

 

5.处理@ImportResource注解

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

// Process any @ImportResource annotations
importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
        if (importResource != null) {
            String[] resources = importResource.getStringArray("locations");
            Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
            String[] var19 = resources;
            int var21 = resources.length;

            for(int var22 = 0; var22 < var21; ++var22) {
                String resource = var19[var22];
                String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
                //把配置项提取出来,跟reader一起放入configClass的map中,
                //接下来会在ConfigurationClassPostProcessor类中processConfigBeanDefinitions方法中,解析完,
                //this.reader.loadBeanDefinitions(configClasses)这方法会对@import处理(对ImportBeanDefinitionRegistrars的处理)
                configClass.addImportedResource(resolvedResource, readerClass);
            }
        }

6.处理@Bean修饰的方法

@Bean方法转化为BeanMethod对象

Set<MethodMetadata> beanMethods = this.retrieveBeanMethodMetadata(sourceClass);
        Iterator var17 = beanMethods.iterator();

        while(var17.hasNext()) {
            MethodMetadata methodMetadata = (MethodMetadata)var17.next();
            //添加到configClass的beanMethods集合中,接下来,会在this.reader.loadBeanDefinitions(configClasses)这方法
            //得到处理
            configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
        }

 

7.处理接口定义的方法

this.processInterfaces(configClass, sourceClass);

8.处理父类

if (sourceClass.getMetadata().hasSuperClass()) {
            String superclass = sourceClass.getMetadata().getSuperClassName();
            if (superclass != null && !superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) {
                this.knownSuperclasses.put(superclass, configClass);
                return sourceClass.getSuperClass();
            }
        }

如果有父类则返回父类Class对象,继续调用该方法。直到返回null,外层循环结束。

do {
            sourceClass = doProcessConfigurationClass(configClass, sourceClass);
        }
        while (sourceClass != null);
posted @ 2020-01-09 17:18  mufeng07  阅读(982)  评论(0编辑  收藏  举报