Spring 源码系列(20): @SpringBootApplication 三注解拆解

📌 阅读前提示 :进入 Spring Boot 阶段(第 20--24 篇) 。Boot 是「约定优于配置」的封装层,但底层全是前面学的 IoC / BPP / 条件注解。本篇先拆 @SpringBootApplication------一个注解背后其实是三个注解的复合,理解它你就拿到了 Boot 自动化的「总开关」。


一、引子:一个注解启动了整个生态

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

@SpringBootApplication 不是新机制,它是三个注解的「语法糖」:

java 复制代码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@SpringBootConfiguration      // = @Configuration(标记配置类)
@EnableAutoConfiguration      // ★ 自动配置的总开关
@ComponentScan(...)           // ★ 包扫描,默认扫当前类所在包及子包
public @interface SpringBootApplication {}

二、三大组成逐一拆解

2.1 @SpringBootConfiguration

就是一个 @Configuration,让你这个启动类本身成为配置源(可在里面写 @Bean)。

java 复制代码
@Configuration
public @interface SpringBootConfiguration {}

2.2 @ComponentScan

默认扫描启动类所在包及其子包 下的 @Component / @Service / @Controller / @Repository。这也是为什么「启动类要放在根包」------扫不到就 Bean 不注册。

⚠️ 易错点 :如果 Controller 放在启动类包之外 且没额外配置 scanBasePackages,这些 Bean 不会被注册,访问就 404。

2.3 @EnableAutoConfiguration(核心)

java 复制代码
@AutoConfigurationPackage        // 把启动类所在包注册进容器(供自动配置按包定位)
@Import(AutoConfigurationImportSelector.class)   // ★ 加载所有自动配置类
public @interface EnableAutoConfiguration {}

AutoConfigurationImportSelector 是自动配置的「发动机」------它读取 META-INF/spring.factories(Boot 2.7 起逐步迁移到 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports),把所有 xxxAutoConfiguration 类批量导入容器。第 21 篇会深挖。


三、三个注解的协作关系

复制代码
@SpringBootApplication
 ├ @SpringBootConfiguration → 启动类成为 @Configuration
 ├ @ComponentScan           → 扫描你的业务 Bean(@Controller/@Service...)
 └ @EnableAutoConfiguration → 导入框架自带的 xxxAutoConfiguration(按条件生效)
        ↓
   你的 Bean + 框架的自动配置 Bean,共同组成一个 ApplicationContext

💡 关键认知 :自动配置类也是普通 @Configuration,只不过它们带 @Conditional 条件------满足条件(比如 classpath 有某个类)才生效。这就是「约定优于配置」的本质。


四、@SpringBootApplication 三注解拆解图


五、常见误区

误区 正解
@SpringBootApplication 是全新机制 不,是 @Configuration+@ComponentScan+@EnableAutoConfiguration 的复合
自动配置类无条件全部生效 错,大多带 @Conditional,按 classpath/环境按需生效
启动类放哪都行 默认只扫启动类所在包及子包,放错位置 Bean 扫不到
@EnableAutoConfiguration 直接 new Bean 不,它 @Import 一个 Selector 去批量导入配置类
自动配置优先级高于你的 @Bean 你的 @Bean 通常优先级更高(可覆盖自动配置,第 21 篇详述)

🧪 面试题自测

  1. @SpringBootApplication 由哪三个注解组成?各自作用?
  2. 为什么启动类要放在根包?
  3. @EnableAutoConfiguration 靠什么类批量导入配置?
  4. 自动配置类为什么不会全部生效?
  5. @SpringBootConfiguration@Configuration 什么关系?
  6. 自动配置和你自己写的 @Bean 冲突时谁优先?

🔧 Debug 小技巧

AutoConfigurationImportSelector.getCandidateConfigurations 打断点,观察它返回的所有自动配置类名(几百个);再在 ConditionEvaluator.shouldSkip 断点,看某个 xxxAutoConfiguration 如何因 @ConditionalOnClass 不满足而被跳过。


下一篇预告

第 21 篇:自动配置原理深挖------AutoConfigurationImportSelector 如何读取配置、如何排序、你的 @Bean 为何能覆盖自动配置;以及 Boot 2.7 的 imports 文件与旧版 spring.factories 的差异。


如果这篇对你有帮助,欢迎 点赞 · 收藏 · 关注 三连支持。

Spring 源码系列共 30 篇,由浅入深持续更新中。有疑问或想深挖的源码点,评论区告诉我,下篇见。

相关推荐
万亿少女的梦1681 小时前
基于Spring Boot、Java与MySQL的同城宠物服务系统设计与实现
java·spring boot·mysql·系统设计·协同过滤
罗小爬EX1 小时前
AI Chat 多类型流式事件处理方案(以AgentScope Java 2为例)
java·人工智能·状态模式
程序员爱钓鱼1 小时前
Rust 生命周期常见错误详解:看懂编译器报错并正确修复
前端·后端·rust
zhanghaha13141 小时前
Python进阶教程:5_XML 解析 —— 新手完全指南
java·前端·数据库
andongni2031 小时前
SpringBoot RESTful API 设计与实现
spring boot·后端·restful
万亿少女的梦1681 小时前
基于Spring Boot、Vue与MySQL的私人健身教练预约管理系统设计
java·spring boot·mysql·vue·预约管理
程序员爱钓鱼1 小时前
Go if 判断详解
前端·后端·go
程序员黑豆1 小时前
Java字符串拼接全解析:6种方式性能对比与实战指南
java·前端·ai编程
万少6 小时前
DeepSeek 昨晚刚开源了 Harness:附万少的2 万字保姆级教程
前端·后端·架构