面试知识库
极高 进阶

SpringBoot自动配置原理#

一句话答案#

@EnableAutoConfiguration 通过候选类发现机制加载配置类,@Conditional 条件过滤,实现约定大于配置。Boot 3 使用 AutoConfiguration.imports 文件,Boot 2 使用 spring.factories

核心要点

当前机制(Boot 3+): @SpringBootApplication → @EnableAutoConfiguration → AutoConfigurationImportSelector → 读取 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports → @Conditional 条件过滤 → 注册符合条件的 Bean

历史机制(Boot 2.x): 同上流程,但候选类注册在 META-INF/spring.factories 中。Boot 2.7 开始同时支持两种文件,Boot 3.0 起 spring.factories 不再用于自动配置类发现。

自定义 Starter: 写 AutoConfiguration 类 + 在 AutoConfiguration.imports 注册(Boot 3)或 spring.factories 注册(Boot 2)

面试回答(2分钟版)

SpringBoot自动配置的核心思想是约定大于配置,通过注解驱动自动装配所需的Bean。入口是@SpringBootApplication中包含的@EnableAutoConfiguration注解,它通过AutoConfigurationImportSelector去发现候选配置类。Boot 3使用META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件注册候选类(每行一个全限定名),Boot 2使用META-INF/spring.factories,Boot 2.7是过渡版本两种都支持。加载到这些配置类后并不是全部生效,而是通过@Conditional系列条件注解进行过滤,比如@ConditionalOnClass判断classpath是否存在某个类、@ConditionalOnBean判断容器中是否已有某个Bean、@ConditionalOnMissingBean判断是否缺少某个Bean、@ConditionalOnProperty判断配置文件中的属性值。只有条件全部满足的配置类才会被加载注册到容器中。这个机制让我们引入一个spring-boot-starter依赖就自动获得相关功能,比如引入spring-boot-starter-web就自动配置好DispatcherServlet、内嵌Tomcat等。自定义Starter也是同样的套路:写一个AutoConfiguration类加上@Conditional条件,在AutoConfiguration.imports(Boot 3)或spring.factories(Boot 2)中注册即可。

追问与易错

追问方向:

  • “@Conditional 有哪些常用派生注解?”→ @ConditionalOnClass(classpath 有某类)、@ConditionalOnMissingBean(容器中无某 Bean)、@ConditionalOnProperty(配置项满足)、@ConditionalOnBean(容器中有某 Bean)、@ConditionalOnWebApplication 等
  • “怎么自定义一个 Starter?”→ 创建 autoconfigure 模块编写 @Configuration 类加 @Conditional 条件注解,创建 starter 模块做依赖聚合,在 AutoConfiguration.imports(Boot 3)或 spring.factories(Boot 2)中注册配置类
  • “自动配置的顺序能控制吗?”→ 可以,用 @AutoConfigureOrder 指定加载优先级,@AutoConfigureBefore/@AutoConfigureAfter 指定相对于其他自动配置类的先后顺序

易错点:

  • ❌ “自动配置就是全部加载”——@Conditional 会过滤大部分配置类
  • ❌ “Boot 3 还用 spring.factories 注册自动配置”——Boot 3 改用 AutoConfiguration.imports,spring.factories 不再用于自动配置发现