@SpringBootApplication所在包是org.springframework.boot:spring-boot-autoconfigure:1.5.22.RELEASE
@SpringBootApplication有三个重要注解,其中有个@EnableAutoConfiguration注解,在@EnableAutoConfiguration注解上有一行
@Import({AutoConfigurationImportSelector.class})
而AutoConfigurationImportSelector实现了ImportSelector接口.重写了selectImports方法
SpringBoot程序启动时,在refresh()方法中
this.invokeBeanFactoryPostProcessors(beanFactory);
org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors
org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions,这里就是处理Config类的逻辑了.
org.springframework.context.annotation.ConfigurationClassUtils#checkConfigurationClassCandidate在这里找到被@Configration标记的类.
Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
然后处理
org.springframework.context.annotation.ConfigurationClassParser#parse(java.util.Set<org.springframework.beans.factory.config.BeanDefinitionHolder>)
org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorHandler#process
org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorGroupingHandler#processGroupImports
org.springframework.context.annotation.ConfigurationClassParser#processImports在这里处理导入的 类
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
最终调用了selectImports方法
if (selector instanceof DeferredImportSelector) { this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector)selector); } else { String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata()); Collection<ConfigurationClassParser.SourceClass> importSourceClasses = this.asSourceClasses(importClassNames, exclusionFilter); this.processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false); }
AutoConfigurationImportSelector实现了DeferredImportSelector接口,所以调用了handle方法.
再来看看 selectImports方法
this.getAutoConfigurationEntry(annotationMetadata);
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getCandidateConfigurations 在这里加载所有的配置类
org.springframework.core.io.support.SpringFactoriesLoader#loadSpringFactories这里加载了
META-INF/spring.factories下的所有字符串
try {
// META-INF/spring.factories
Enumeration<URL> urls = classLoader.getResources(FACTORIES_RESOURCE_LOCATION);
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
for (Map.Entry<?, ?> entry : properties.entrySet()) {
String factoryTypeName = ((String) entry.getKey()).trim();
String[] factoryImplementationNames =
StringUtils.commaDelimitedListToStringArray((String) entry.getValue());
for (String factoryImplementationName : factoryImplementationNames) {
result.computeIfAbsent(factoryTypeName, key -> new ArrayList<>())
.add(factoryImplementationName.trim());
}
}
}
// Replace all lists with unmodifiable lists containing unique elements
result.replaceAll((factoryType, implementations) -> implementations.stream().distinct()
.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList)));
cache.put(classLoader, result);
}
最后返回了一个数组,包含了所有需要自动导入的类的全限定名,就是META-INF/spring.factories的值
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
}
然后是bean初始化的那一套了
this.registerBeanPostProcessors(beanFactory); this.initMessageSource(); this.initApplicationEventMulticaster(); this.onRefresh(); this.registerListeners(); this.finishBeanFactoryInitialization(beanFactory); this.finishRefresh();
参考: