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