08、SpringBoot 源码分析 - 自动配置深度分析一

SpringBoot 源码分析 - 自动配置深度分析一

refresh和自动配置大致流程

如何自动配置

我们看下这段代码,红色框是什么放入的注册类,其实这就是我们要注册的配置类,自动装配跟他有关:

java 复制代码
public static void main(String[] args) {
		SpringApplication.run(SpringBootLearnApplication.class, args);
	}

为什么呢,因为他头上有注解 SpringBootApplication

java 复制代码
@SpringBootApplication
public class SpringBootLearnApplication

所以其实你只要传一个头上有这个注解的类就可以了,不一定要是main方法的类。

SpringBootApplication注解

那为什么就有这个注解就能自动配置呢,我们来看看这个注解,其他你可以不管,但是EnableAutoConfiguration你得看:

首先这个是一个配置类,可以被解析,因为有SpringBootConfiguration注解,被Configuration注解了:

这样我们的SpringBootApplication就类似于我们经常配置的java配置类。有了这个前提,我们就可以先看这个配置类的解析过程,其实就是ConfigurationClassPostProcessor的解析处理,解析流程我以前的spring源码文章都讲过,其中processImports的处理也特别讲过,会先递归获取所有import进来的类,然后按不同类型进行判断处理,重点就是这里啦,我们先来看下EnableAutoConfiguration注解是不是有import呢。

EnableAutoConfiguration注解

有个AutoConfigurationImportSelectorimport,其实还有一个在AutoConfigurationPackage注解里,暂时不说,重点是AutoConfigurationImportSelector

AutoConfigurationImportSelector自动配置导入选择器

看下他的结构,左边不用管,就是为了回调拿到一些属性,好对容器操作,主要是右边,我们前面spring的文章讲过ImportSelector的原理,想看的朋友可以看下这篇文章,有这个基础对下面的理解比较好,因为这里还有个DeferredImportSelector,他会在ConfigurationClassParser解析方法的最后来处理。

可以看到,他被处理的时候:

DeferredImportSelectorHandler就是专门来处理这些DeferredImportSelector的。

DeferredImportSelectorHandler的handle

首先会封装一个持有器DeferredImportSelectorHolder,如果deferredImportSelectors为空,表示在被DeferredImportSelectorGroupingHandler处理中,DeferredImportSelectorGroupingHandler又是什么呢,其实我们要处理的DeferredImportSelectorHolder会根据Group进行分组,来区分不同的ImportSelector,比如我们这个自动装配的AutoConfigurationImportSelector,是属于AutoConfigurationGroup类型的,分组处理方便,到时候只需要遍历所有组中的ImportSelector统一处理即可。因为处理的方式是迭代器循环,所以不能添加,只能直接处理,当然如果不为空,表示没有在处理,可以添加到deferredImportSelectors集合里。

java 复制代码
		public void handle(ConfigurationClass configClass, DeferredImportSelector importSelector) {
   
     
			DeferredImportSelectorHolder holder = new DeferredImportSelectorHolder(configClass, importSelector);
			if (this.deferredImportSelectors == null) {
   
     //直接处理
				DeferredImportSelectorGroupingHandler handler = new DeferredImportSelectorGroupingHandler();
				handler.register(holder);
				handler.processGroupImports();
			}
			else {
   
     
				this.deferredImportSelectors.add(holder);//添加
			}
		}

DeferredImportSelectorGroupingHandler的register注册DeferredImportSelectorHolder

可以看到组处理器里面会有一个groupings 映射,就是来存放Group类别和DeferredImportSelectorGrouping映射的,同一个Group类别里面可以很多个DeferredImportSelectorGrouping,因为DeferredImportSelectorGrouping里面有集合。

java 复制代码
		//自动装配类型和组映射
		private final Map<Object, DeferredImportSelectorGrouping> groupings = new LinkedHashMap<>();
		//注解属性和配置类的映射
		private final Map<AnnotationMetadata, ConfigurationClass> configurationClasses = new HashMap<>();
		//注册分组
		public void register(DeferredImportSelectorHolder deferredImport) {
   
     
			Class<? extends Group> group = deferredImport.getImportSelector().getImportGroup();
			DeferredImportSelectorGrouping grouping = this.groupings.computeIfAbsent(
					(group != null ? group : deferredImport),
					key -> new DeferredImportSelectorGrouping(createGroup(group)));//创建组
			grouping.add(deferredImport);//创建一个组,并加入DeferredImportSelectorHolder
			this.configurationClasses.put(deferredImport.getConfigurationClass().getMetadata(),
					deferredImport.getConfigurationClass());//将注解属性和ConfigurationClass映射
		}

DeferredImportSelectorGrouping

这里就是同一个组的会添加进deferredImports集合。

其实是比较绕的,绕了几层,我画个图看了清晰:

相关推荐
接着奏乐接着舞19 分钟前
springboot mp mybatis plaus
windows·spring boot·mybatis
金融支付架构实战指南26 分钟前
Milvus 向量检索服务 + SpringBoot 实战:电商商品语义检索与相似商品推荐
spring boot·后端·milvus·向量检索
技术小结-李爽27 分钟前
【工具】Maven的使用
java·maven
sou_time29 分钟前
从 0 到 商用:AI Agent x SKILL x MCP 全栈实战教程:L2 高等篇:MCP 协议 + Spring AI + Agent 编排
java·人工智能·spring
冷小鱼34 分钟前
高级研发编码习惯:从规范到艺术,再到AI+时代的人机协同
java·开发语言·python·编码习惯
齐 飞38 分钟前
JDK21虚拟线程
java·后端
小马爱打代码42 分钟前
Java 并发 Bug 深度分析与实战
java
fox_lht1 小时前
15.4.循环和迭代器的性能比较
开发语言·后端·学习·rust
极客先躯1 小时前
高级java每日一道面试题-2026年02月09日-实战篇[Docker]-Docker 容器有哪些安全风险?如何缓解?
java·运维·网络·安全·docker·容器
_Aaron___1 小时前
MyBatis 动态排序别乱用 ${}:ORDER BY 的安全写法
java·spring·mybatis