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 篇,由浅入深持续更新中。有疑问或想深挖的源码点,评论区告诉我,下篇见。

相关推荐
实名上网宋凯宣3 小时前
Django
后端·python·django
天河归来4 小时前
第三方接口不稳定,如何让核心任务继续完成
java·大数据
Knight_AL5 小时前
Java 文件下载时文件名中的 `#` 被转换成 `%23`?一次 URL 编码与解码问题排查
java·开发语言
利威尔xu5 小时前
Go IM 源码实战(14):本地缓存快 3000 倍,失效却难 10 倍
后端·缓存·微服务·面试·golang
逃逸线LOF6 小时前
Ribbon负载均衡原理(Irule组件、源码分析)
后端·spring cloud·ribbon
砚底藏山河6 小时前
python量化自定义周期 K 线合成
java·开发语言·数据库·python·金融
慢云智慧空间6 小时前
从设备智能到空间理解,空间智能终端解决方案商如何重新定义行业标准
后端
利威尔xu6 小时前
Go IM 源码实战(13):30 个会话只有 2 个红点,未读数错在三条路径
redis·后端·微服务·面试·golang
猿究院_夏燊7 小时前
MySQL 的四种隔离级别
java·数据库·mysql
薛定谔的猫-菜鸟程序员7 小时前
软件架构设计师开发资料大全(从入门到精通)
后端·python·系统架构·flask·架构设计师