通过SpringBoot之Spi机制加载Spring.factories 、SpringBoot之解析启动类源码分析已经得到IOC容器中所有的类的相关信息。
对于用户自定义的类在解析启动类扫描包路径下的过程中就已经完成其AnnotatedGenericBeanDefinition类型的BeanDefinitions的初始化。
本文主要解析特殊类的BeanDefinitions的初始化。特殊类包括:ImportBeanDefinitionRegistrar「启动类对应的AutoConfigurationPackages.Registrar、Mybatis对应的MapperScannerRegistrar」、@Import 注解的类、@Bean注解的类。
public class ConfigurationClassPostProcessor{
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
...
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator,
registry);
do {
//ConfigurationClassParser#parse
parser.parse(candidates);
parser.validate();
...
}
...
this.reader.loadBeanDefinitions(configClasses);
while (!candidates.isEmpty());
}
}
this.reader.loadBeanDefinitions:其实就是对spring.factories文件中的候选类以及其间接加载的候选类触发BeanDefinitions的初始化。
class ConfigurationClassBeanDefinitionReader {
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
for (ConfigurationClass configClass : configurationModel) {
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}
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());
}
}
configClass.isImported():表示当前候选类是否是通过@Import注解生效的。并非当前候选类是否存在@Import注解。
1、处理ImportBeanDefinitionRegistrar类型的候选类
private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {
registrars.forEach((registrar, metadata) ->
registrar.registerBeanDefinitions(metadata, this.registry));
}
configClass.getImportBeanDefinitionRegistrars():候选类中获取ImportBeanDefinitionRegistrar类型的类。其中ImportBeanDefinitionRegistrar类型的子类是通过解析@import时添加到候选类中。