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(); }
} }