Spring Boot 机制一: 自动配置原理源码级深度讲解 - 教程

博主社群介绍: ① 群内初中生、高中生、本科生、研究生、博士生遍布,可互相学习,交流困惑。
② 热榜top10的常客也在群里,也有数不清的万粉大佬,可以交流写作技巧,上榜经验,涨粉秘籍。
③ 群内也有职场精英,大厂大佬,跨国企业主管,可交流技术、面试、找工作的经验。
进群免费赠送写作秘籍一份,助你由写作小白晋升为创作大佬,进群赠送CSDN评论防封脚本,送真活跃粉丝,助你提升文章热度。
群公告里还有全网大赛约稿汇总/博客提效工具集/CSDN自动化运营脚本 有兴趣的加文末联系方式,备注自己的CSDN昵称,拉你进群,互相学习共同进步。

img

结束语

Spring Boot 机制一: 自动配置原理源码级深度讲解

适合读者:
中高级 Java / Spring Boot 工程师;希望理解自动配置底层、掌握 Starter 编写方法、阅读 Spring Boot 源码的读者。


目录

  1. 自动配置的整体概念
  2. AutoConfiguration 的核心机制
  3. 条件注解(Conditional 系列)全解析
  4. Spring Boot 启动流程与自动配置生效链路
  5. Binder:配置绑定到底怎么实现的?
  6. 如何自定义一个 Starter
  7. 自动配置的调试技巧
  8. 实战:编写一个自动配置的组件

1. 自动配置的整体概念

1.1 什么是自动配置?

Spring Boot 的核心卖点就是:

「约定优于配置,让开发者只关注业务,不关注框架细节。」

当你引入 spring-boot-starter-web 时,不需要写任何 XML 或手动注册 DispatcherServlet,Spring Boot 会自动帮你按规则完成配置。

例如:

  • 自动创建 Tomcat 容器
  • 自动注册 DispatcherServlet
  • 自动配置 HandlerMapping
  • 自动开启 Spring MVC 默认配置

这背后依赖的就是:

AutoConfiguration + Condition 机制


1.2 自动配置怎么被加载?

核心入口:
spring-boot-autoconfigure 模块中的以下文件:

META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

里面罗列所有自动配置类,例如:

org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
...

它们会在应用启动时加载。

下面这张图展示了自动配置的整体流程:

flowchart TD
    A[启动 Spring Boot 应用] --> B[加载主类 @SpringBootApplication]
    B --> C[@EnableAutoConfiguration 导入自动配置]
    C --> D[读取 AutoConfiguration.imports 列表]
    D --> E[对每项自动配置执行 Condition 评估]
    E --> F{条件是否满足?}
    F -->|是| G[注册自动配置 BeanDefinition]
    F -->|否| H[跳过自动配置]
    G --> I[应用启动完成]
    H --> I[应用启动完成]

图1:自动配置加载流程


2. AutoConfiguration 的核心机制

2.1 @SpringBootApplication 做了什么?

实际上它是一个复合注解:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication {}

核心是 @EnableAutoConfiguration


2.2 @EnableAutoConfiguration 如何工作?

它使用:

@Import(AutoConfigurationImportSelector.class)

于是自动进入 AutoConfigurationImportSelector 的加载逻辑。

核心方法:

public String[] selectImports(AnnotationMetadata metadata) {
List<String> configurations = getCandidateConfigurations(metadata, attributes);
  return configurations.toArray(new String[0]);
  }

getCandidateConfigurations 内部做了:

读取 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

从而获取所有自动配置类。


2.3 AutoConfiguration 和 SpringFactories 的关系

Spring Boot 2.x 使用:

META-INF/spring.factories

Spring Boot 3.x 使用:

META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

二者作用等价,只是新版拆分了文件。

表1 对比两者:

版本自动配置文件格式状态
Spring Boot 2.xspring.factorieskey=value旧方式(兼容)
Spring Boot 3.xAutoConfiguration.imports每行一个类推荐方式

3. 条件注解(Conditional 系列)全解析

自动配置是否生效的关键依靠:

@Conditional 系列注解

常见的有:

注解作用
@ConditionalOnClassclasspath 中有某个类
@ConditionalOnMissingClassclasspath 中没有某个类
@ConditionalOnBeanSpring 容器已存在某 Bean
@ConditionalOnMissingBeanSpring 容器不存在某 Bean
@ConditionalOnProperty某属性存在或为某值
@ConditionalOnWebApplicationWeb 环境才生效

例如:DispatcherServletAutoConfiguration 里有:

@ConditionalOnClass(DispatcherServlet.class)
@AutoConfiguration
public class DispatcherServletAutoConfiguration {
}

如果你不引入 spring-webmvc,那么这个类不会被加载。


3.1 Condition 的源码解析

所有条件注解最终会归到:

SpringBootCondition

例如 ConditionOutcome 决定是否匹配成功。

核心执行链:

public ConditionOutcome getMatchOutcome(...) {
// 收集上下文
// 匹配注解
// 得到是否满足条件
}

Spring Boot 在启动期间会输出:

===========================
AUTO-CONFIGURATION REPORT
===========================

用于展示哪些自动配置生效、哪些被跳过。


4. Spring Boot 启动流程与自动配置生效链路

下面是完整链路:

用户主类 SpringApplication AutoConfigurationImportSelector ConditionEvaluator ApplicationContext run() prepareContext() 读取所有自动配置类 对每个自动配置类执行条件评估 返回是否满足 注册满足条件的 Configuration 扫描 + 实例化 Bean 完成启动 用户主类 SpringApplication AutoConfigurationImportSelector ConditionEvaluator ApplicationContext

5. Binder:配置绑定到底怎么实现的?

自动配置类通常包含属性绑定,例如:

@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourceProperties {}

Spring Boot 内部使用:

org.springframework.boot.context.properties.bind.Binder

来实现:

  • 类型转换
  • 嵌套属性绑定
  • Map / List 绑定
  • 默认值注入

核心源码:

public <T> T bind(String name, Bindable<T> target) {
  return bindObject(name, target, context, false);
  }

Binder 是一个很大的主题,如果你需要,我可以单独帮你写一篇 3000 字深度文章。


6. 如何自定义一个 Starter

自动配置的最大价值是:

封装模块,提高项目通用性、复用性

例如:

acme-spring-boot-starter
acme-spring-boot-autoconfigure

最简单示例结构:

my-starter
 ├── starter
 └── autoconfigure

自动配置类:

@Configuration
@ConditionalOnClass(MyService.class)
@EnableConfigurationProperties(MyProperties.class)
public class MyServiceAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public MyService myService(MyProperties props) {
return new MyService(props.getName());
}
}

配置文件:

META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

内容:

com.example.autoconfig.MyServiceAutoConfiguration

完成!


7. 自动配置的调试技巧

常用:

7.1 开启 debug 模式

java -jar app.jar --debug

或者在 application.yml 中:

debug: true

会输出自动配置报告:

Positive matches:
Negative matches:

7.2 使用 ConditionEvaluationReport

你可以通过 Actuator 查看:

/actuator/conditions

可直接看到每个自动配置的匹配情况。


7.3 使用 IDE 查看自动配置类是否被加载

例如:
查看某个自动配置类是否被注册
或查看 Bean Definition Source。


8. 实战:实现一个「自动日志追踪」Starter

我们写一个:

请求进入 → 自动记录 traceId → 方法执行 → 记录耗时

8.1 创建配置类

@Configuration
@EnableConfigurationProperties(TraceProperties.class)
@ConditionalOnProperty(prefix = "trace", name = "enabled", havingValue = "true")
public class TraceAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public TraceInterceptor traceInterceptor() {
return new TraceInterceptor();
}
}

8.2 Properties

@ConfigurationProperties(prefix = "trace")
public class TraceProperties {
private boolean enabled = true;
}

8.3 拦截器

public class TraceInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) {
MDC.put("traceId", UUID.randomUUID().toString());
return true;
}
@Override
public void afterCompletion(HttpServletRequest req, HttpServletResponse res, Object handler, Exception ex) {
MDC.clear();
}
}

8.4 自动配置导入文件

META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

内容:

com.example.TraceAutoConfiguration

即可完成一个完整的可复用 Starter。


结束语


‍ 关于我

持续学习 | 追求真我

如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的。想看更多 那就点个关注吧 我会尽力带来有趣的内容 。

感谢订阅专栏 三连文章

image-20251011155556997

掘金点击访问QiunerCSDN点击访问QiunerGitHub点击访问QiunerGitee点击访问Qiuner

专栏简介
一图读懂系列图文并茂,轻松理解复杂概念
一文读懂系列深入浅出,全面解析技术要点
持续更新保持学习,不断进步
人生经验经验分享,共同成长

你好,我是Qiuner. 为帮助别人少走弯路而写博客

如果本篇文章帮到了你 不妨点个吧~ 我会很高兴的 (^ ~ ^) 。想看更多 那就点个关注吧 我会尽力带来有趣的内容 。

代码都在Github或Gitee上,如有需要可以去上面自行下载。记得给我点星星哦

如果你遇到了问题,自己没法解决,可以去我掘金评论区问。CSDN评论区和私信消息看不完 掘金消息少一点.

上一篇推荐链接
Java程序员快又扎实的学习路线点击该处自动跳转查看哦
一文读懂 AI点击该处自动跳转查看哦
一文读懂 服务器点击该处自动跳转查看哦
2024年创作回顾点击该处自动跳转查看哦
一文读懂 ESLint配置点击该处自动跳转查看哦
老鸟如何追求快捷操作电脑点击该处自动跳转查看哦
未来会写什么文章?预告链接
一文读懂 XX?点击该处自动跳转查看哦
2025年终总结点击该处自动跳转查看哦
一图读懂 XX?点击该处自动跳转查看哦

img

posted @ 2025-12-20 15:34  yangykaifa  阅读(0)  评论(0)    收藏  举报