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; }
ConfigurationClassParser类的parse方法源码解析
原文:https://www.cnblogs.com/mufeng07/p/12172549.html