SpringBoot main方法所在类添加了注解@SpringBootApplication, 在此注解中添加了注解@EnableAutoConfiguration, 默认开启了自动配置
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
...
}
AutoConfigurationImportSelector实现了DeferredImportSelector接口, 表示为延迟导入, 在Spring容器初始化时, 对此添加了判断, 所以初始化过程中没有执行但是AutoConfigurationImportSelector.selectImports方法
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector
public class AutoConfigurationImportSelector
implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware,
BeanFactoryAware, EnvironmentAware, Ordered {
...
}
为什么没有执行org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#selectImports方法
org.springframework.context.annotation.ConfigurationClassParser.processImports
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, boolean checkForCircularImports) {
...
if (candidate.isAssignable(ImportSelector.class)) {
// Candidate class is an ImportSelector -> delegate to it to determine imports
Class<?> candidateClass = candidate.loadClass();
ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
ParserStrategyUtils.invokeAwareMethods(
selector, this.environment, this.resourceLoader, this.registry);
if (selector instanceof DeferredImportSelector) { // 如果实现了接口DeferredImportSelector 则添加到名为deferredImportSelectors的list中暂存
this.deferredImportSelectorHandler.handle(
configClass, (DeferredImportSelector) selector);
}
else { // 否则执行selectImports方法
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
processImports(configClass, currentSourceClass, importSourceClasses, false);
}
}
...
}
程序调用栈信息
processImports:565, ConfigurationClassParser (org.springframework.context.annotation)
doProcessConfigurationClass:302, ConfigurationClassParser (org.springframework.context.annotation)
processConfigurationClass:242, ConfigurationClassParser (org.springframework.context.annotation)
parse:199, ConfigurationClassParser (org.springframework.context.annotation)
parse:167, ConfigurationClassParser (org.springframework.context.annotation)
processConfigBeanDefinitions:315, ConfigurationClassPostProcessor (org.springframework.context.annotation)
postProcessBeanDefinitionRegistry:232, ConfigurationClassPostProcessor (org.springframework.context.annotation)
invokeBeanDefinitionRegistryPostProcessors:275, PostProcessorRegistrationDelegate (org.springframework.context.support)
invokeBeanFactoryPostProcessors:95, PostProcessorRegistrationDelegate (org.springframework.context.support)
invokeBeanFactoryPostProcessors:691, AbstractApplicationContext (org.springframework.context.support)
refresh:528, AbstractApplicationContext (org.springframework.context.support)
refresh:142, ServletWebServerApplicationContext (org.springframework.boot.web.servlet.context)
refresh:775, SpringApplication (org.springframework.boot)
refreshContext:397, SpringApplication (org.springframework.boot)
run:316, SpringApplication (org.springframework.boot)
run:1260, SpringApplication (org.springframework.boot)
run:1248, SpringApplication (org.springframework.boot)
main:18, SpringWebApplication (com.cloud.demo)
AutoConfiguration初始化流程
SpringBoot在启动过程中, 会初始化Spring容器, 首要做的就是扫描文件, 创建BeanDefinition对象存储到容器中
程序调用栈
parse:185, ConfigurationClassParser (org.springframework.context.annotation)
processConfigBeanDefinitions:315, ConfigurationClassPostProcessor (org.springframework.context.annotation)
postProcessBeanDefinitionRegistry:232, ConfigurationClassPostProcessor (org.springframework.context.annotation)
invokeBeanDefinitionRegistryPostProcessors:275, PostProcessorRegistrationDelegate (org.springframework.context.support)
invokeBeanFactoryPostProcessors:95, PostProcessorRegistrationDelegate (org.springframework.context.support)
invokeBeanFactoryPostProcessors:691, AbstractApplicationContext (org.springframework.context.support)
refresh:528, AbstractApplicationContext (org.springframework.context.support)
refresh:142, ServletWebServerApplicationContext (org.springframework.boot.web.servlet.context)
refresh:775, SpringApplication (org.springframework.boot)
refreshContext:397, SpringApplication (org.springframework.boot)
run:316, SpringApplication (org.springframework.boot)
run:1260, SpringApplication (org.springframework.boot)
run:1248, SpringApplication (org.springframework.boot)
main:18, SpringWebApplication (com.cloud.demo)
org.springframework.context.annotation.ConfigurationClassParser.parse
public void parse(Set<BeanDefinitionHolder> configCandidates) {
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
if (bd instanceof AnnotatedBeanDefinition) {
// 先解析扫描bean, 在此方法中向deferredImportSelectorHandler中添加了一个对象, 存储了可延迟导入的selector列表
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}
else {
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
}
}
// 执行对象的process方法
this.deferredImportSelectorHandler.process();
}
org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorHandler.process
public void process() {
List<DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors;
this.deferredImportSelectors = null; // 清空
try {
if (deferredImports != null) {
DeferredImportSelectorGroupingHandler handler = new DeferredImportSelectorGroupingHandler();
deferredImports.sort(DEFERRED_IMPORT_COMPARATOR); // 排序 按照优先级、sort大小排序
deferredImports.forEach(handler::register);
handler.processGroupImports();
}
}
finally {
this.deferredImportSelectors = new ArrayList<>();
}
}
org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorGroupingHandler.register
public void register(DeferredImportSelectorHolder deferredImport) {
// 调用org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.getImportGroup 返回AutoConfigurationGroup.class
Class<? extends Group> group = deferredImport.getImportSelector().getImportGroup();
// 创建Group对象, 用DeferredImportSelectorGrouping包装并存入到map中
DeferredImportSelectorGrouping grouping = this.groupings.computeIfAbsent(
(group != null ? group : deferredImport),
key -> new DeferredImportSelectorGrouping(createGroup(group)));
// 向deferredImports对象添加元素, 后面会使用
grouping.add(deferredImport);
// 存入map中 key为启动类的元数据 value是启动类
this.configurationClasses.put(deferredImport.getConfigurationClass().getMetadata(),
deferredImport.getConfigurationClass());
}
org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorGroupingHandler.processGroupImports
public void processGroupImports() {
for (DeferredImportSelectorGrouping grouping : this.groupings.values()) { // 只有一个元素, 上个方法放入的
grouping.getImports().forEach(entry -> { // 重点解析
// 获取主配置类 启动类
ConfigurationClass configurationClass = this.configurationClasses.get(entry.getMetadata());
try {
// 逐个执行导入 至此执行完成后, 扫描出的类都会注册到BeanDefinition中 等待Spring容器对对象实例化和初始化
processImports(configurationClass, asSourceClass(configurationClass),
asSourceClasses(entry.getImportClassName()), false);
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to process import candidates for configuration class [" +
configurationClass.getMetadata().getClassName() + "]", ex);
}
});
}
}
org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorGrouping.getImports
public Iterable<Group.Entry> getImports() {
// 前面放入的一个元素 此处循环
for (DeferredImportSelectorHolder deferredImport : this.deferredImports) {
// group为AutoConfigurationGroup对象 执行org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.AutoConfigurationGroup.process方法
this.group.process(deferredImport.getConfigurationClass().getMetadata(),
deferredImport.getImportSelector());
}
// 对map结果去重、排序并返回
return this.group.selectImports();
}
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.AutoConfigurationGroup.process
public void process(AnnotationMetadata annotationMetadata,
DeferredImportSelector deferredImportSelector) {
// 断言
Assert.state(
deferredImportSelector instanceof AutoConfigurationImportSelector,
() -> String.format("Only %s implementations are supported, got %s",
AutoConfigurationImportSelector.class.getSimpleName(),
deferredImportSelector.getClass().getName()));
// 调用getAutoConfigurationEntry检索spring.factories文件, 存储并排除文件中配置的bean
AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector)
.getAutoConfigurationEntry(getAutoConfigurationMetadata(), // 获取了所有包中的spring.factories文件配置参数
annotationMetadata);
this.autoConfigurationEntries.add(autoConfigurationEntry);
for (String importClassName : autoConfigurationEntry.getConfigurations()) {
// 将过滤后的类存入到entries map中
this.entries.putIfAbsent(importClassName, annotationMetadata);
}
}
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.getAutoConfigurationEntry
protected AutoConfigurationEntry getAutoConfigurationEntry(
AutoConfigurationMetadata autoConfigurationMetadata,
AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
// 获取EnableAutoConfiguration注解的属性
AnnotationAttributes attributes = getAttributes(annotationMetadata);
// 扫描各个包下META-INF/spring.factories文件中配置EnableAutoConfiguration 大约100+
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
// Link转Array
configurations = removeDuplicates(configurations);
// 获取注解上排除的类 @SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
// 去掉排除的类
configurations.removeAll(exclusions);
// 使用filter过滤 过滤不存在的类(尝试加载 异常说明不存在)
configurations = filter(configurations, autoConfigurationMetadata);
// 发送一个AutoConfigurationImportEvent事件通知
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}