此处处理的是在配置类中具有@Bean注解的方法
// ①
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
	// ②
	configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// ④
private void processInterfaces(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
	for (SourceClass ifc : sourceClass.getInterfaces()) {
		Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(ifc);
		for (MethodMetadata methodMetadata : beanMethods) {
			if (!methodMetadata.isAbstract()) {
// A default method or other concrete method on a Java 8+ interface...
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
			}
		}
		processInterfaces(configClass, ifc);
	}
}
// ⑤
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();
	}
}
① - 获取所有具有@Bean注解的方法
② - 将获取到的方法包装为BeanMethod对象(表示一个具有@Bean注解的@Configuration类的方法)保存到当前配置类的beanMethods属性中
④ - 处理接口中具有@Bean注解的方法
⑤ - 处理父类中具有@Bean注解的方法
取出@Configuration
直接从Parser中取出之前解析时缓存的配置类,因为这段代码在do-while循环中,因此首先移除已处理的。
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
构建BeanDefinitionReader
若Reader为空,则创建,用于读取配置中的BeanDefinition
if (this.reader == null) {
	this.reader = new ConfigurationClassBeanDefinitionReader(
			registry, this.sourceExtractor, this.resourceLoader, this.environment,
			this.importBeanNameGenerator, parser.getImportRegistry());
}
@Configuration读取BeanDefinition
前面对各种注解的的解析最终并没有处理解析的结果,而是将其放在了ConfigurationClass对象的属性当中存储,在这里将通过Reader来处理这
些不同来源的BeanDefinition。
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
	TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
	// ①
	for (ConfigurationClass configClass : configurationModel) {
		// ②
		loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
	}
}
① - 遍历所有的@Configuration
② - 从@Configuration读取BeanDefinition
private void loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
	// ①
	if (trackedConditionEvaluator.shouldSkip(configClass)) {
		String beanName = configClass.getBeanName();
		if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
			this.registry.removeBeanDefinition(beanName);
		}
		this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
		return;
	}
	// ②
	if (configClass.isImported()) {
		registerBeanDefinitionForImportedConfigurationClass(configClass);
	}
	
	// ③
	for (BeanMethod beanMethod : configClass.getBeanMethods()) {
		loadBeanDefinitionsForBeanMethod(beanMethod);
	}
	// ④
	loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
	
	// ⑤
	loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
① - 是否需要跳过
② - 当前配置类本身是否通过@Import导入,若有则将自身注册为BeanDefinition
③ - 当前配置类中是否有@Bean注解修饰的方法,若有则处理
④ - 加载从@ImportResource导入的XML文件中定义的Bean
⑤ - 加载从@Import导入的BeanDefinition
合并已处理的BeanDefinition
// ①
String[] candidateNames = registry.getBeanDefinitionNames();
if (registry.getBeanDefinitionCount() > candidateNames.length) {
	// ②
	String[] newCandidateNames = registry.getBeanDefinitionNames();
	// ③
	Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
	// ④
	Set<String> alreadyParsedClasses = new HashSet<>();
	// ⑤
	for (ConfigurationClass configurationClass : alreadyParsed) {
		alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
	}
	
	// ⑥
	for (String candidateName : newCandidateNames) {
		// ⑦
		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;
}