Spring Boot · 机制级深潜 · 概念为主

把 Spring Boot 拆成一条 refresh() 流水线

基于 Spring Boot 4.0.x(截至 2026-06 的最新稳定 GA · Spring Framework 7 · Jakarta EE 11 · Java 17 基线)· 深潜(约半天)· 概念为主,代码为讲机制的示意(未在本机跑完整 Maven 构建)。这份教程不教你抄一遍 start.spring.io 的 quickstart,而是给你一张结构图——能在启动报错、面试被追问"自动配置怎么生效"、读陌生 starter 源码这三个场景里精确定位机制。

A适合谁

这份教程面向已经会用 Spring Boot、想从"会写注解"升级到"懂容器机制"的 Java 工程师。需要三项基础:

  • 写过 Spring Boot 应用:用过 @RestController、@Service、@Autowired、application.yml,知道 @SpringBootApplication 标在主类上。教程不重教"怎么起一个项目"。
  • 懂 Java 基础与一点反射 / 代理概念:知道接口与实现、什么是动态代理(哪怕只是听过 JDK Proxy / CGLIB)。第 4 章会下探到字节码层。
  • 读过异常栈、调过启动失败:见过 NoSuchBeanDefinitionException、BeanCurrentlyInCreationException 这类报错。教程把这些报错还原成机制。

B不适合谁

  • 没写过 Java / 没碰过 Spring:这里不会重讲依赖注入是什么、注解怎么用。先过一遍官方 Building an Application with Spring Boot,再回来。
  • 只想要一段能跑的 CRUD 代码:去 start.spring.io 生成、照 Baeldung 抄。这份教程讲的是那段代码背后容器在做什么、什么时候会崩。
  • 想深入 Netty / 响应式 WebFlux 全栈:本教程聚焦 Servlet 栈与容器核心机制;响应式只在第 6 章点到。那是另一个主题。

C读完之后你能做到什么

核心收获,一句话:Spring Boot 的所有"魔法"都还原成同一件事——容器在 refresh() 里先收集 Bean 蓝图、再用 BeanPostProcessor 把对象换成代理:自动配置是带 @Conditional 的有序 @Bean 注册,@Transactional 是代理拦截,内嵌 Tomcat 在 refresh 中途启动。掌握这条流水线,你 debug 启动问题、面试被追问机制、读陌生 starter 源码时,定位的是机制而不是背结论。这是只读 quickstart 的人给不出的视角。

具体到可验证的能力:

  • 画出 SpringApplication.run() → refresh() 的阶段时序,并说清内嵌 Tomcat 在哪一步启动、为什么早于单例预实例化。
  • 解释一个 starter 加进 classpath 后,它的自动配置如何被发现、如何被 @Conditional 筛选、为什么"你写的 @Bean 总能覆盖默认配置"。
  • 判断为什么 this.txMethod() 自调用会让 @Transactional 失效——并说出根因在代理而非注解。
  • 追踪一个 HTTP 请求从内嵌 Tomcat 经 DispatcherServlet 到 controller 的路径,以及一条配置属性从 application.yml 经 Environment 绑定到 POJO 的优先级。
  • 选型与判别:说清 Spring 的运行时反射 + AOT 与 Quarkus / Micronaut 的编译期 DI 差在哪、何时该开虚拟线程、三条快启动路线(CDS / 原生镜像 / AOT cache)各解决什么。

一句话本质

Spring Boot 没有魔法。容器启动时跑一条固定的 refresh() 流水线:先用 BeanFactoryPostProcessor 收集并改写所有 Bean 蓝图(BeanDefinition),再用 BeanPostProcessor 逐个加工 Bean 实例。"自动配置"只是按 classpath 和 Environment 条件决定注册哪些带 @Conditional 的 @Bean;"@Transactional 的魔法"只是某个 BeanPostProcessor 把你的对象换成了代理。记住"容器 = 带条件的 Bean 注册 + 把对象换成代理的后置处理流水线",所有魔法都还原成有序执行的普通代码。

这句话里藏着三根贯穿全教程的支柱:①两类后置处理器(BeanFactoryPostProcessor 改"蓝图"、BeanPostProcessor 改"实例"——这是区分一切机制的第一刀);②条件化注册(自动配置不是黑魔法,是按 classpath/环境求值的 @Conditional + 有序执行);③代理替换(事务、缓存、异步、安全全是某个 BeanPostProcessor 把你的 Bean 换成代理——也是大半"注解不生效"问题的根源)。

D现状速览(截至 2026-06)

什么稳了 · 什么在变 · 什么过时了

已稳定(放心学):IoC 容器与 Bean 生命周期、ApplicationContext.refresh() 流水线、两类后置处理器、基于代理的 AOP、DispatcherServlet 请求模型——这套核心机制从 Spring 3 至今骨架未变,是本教程的主体。GraalVM 原生镜像、Micrometer Observation 自 Spring Boot 3.0(2022-11)起也已稳定。

当前版本:Spring Boot 4.0.x(4.0.6 / 2026-04,最新稳定 GA),基线 Spring Framework 7 + Jakarta EE 11(jakarta.*)+ Jackson 3 默认 + Java 17 起步(构建用到 Java 25);移除了 Undertow 内嵌容器。3.5.x(3.5.14)是并行维护分支。4.1.0-RC1(2026-04)已出、GA 在即但尚未发布。

仍在快速演进(学时带上日期):Spring AI(1.1 GA / 2025-11,含 ChatClient、向量库、工具调用、MCP 集成);三条快启动路线并存——CDS、GraalVM 原生镜像、Java 25 的 AOT cache(4.1 引入);虚拟线程(spring.threads.virtual.enabled,3.2 起)正走向默认化。

已被取代(别学旧法):spring.factories 注册自动配置 → META-INF/spring/…AutoConfiguration.imports(2.7 起);Spring Cloud Sleuth → Micrometer Tracing(Sleuth 未移植到 Boot 3+);javax.* → jakarta.*(3.0 起);RestTemplate → RestClient(3.2 起)。

读之前 · 一个关于"读懂了"的警告

Spring Boot 的每个概念单看都眼熟(Bean、注解、容器),连起来读会很顺。但"顺"是危险信号,不是学会的证据——几个关键点恰恰违反直觉(自动配置"用户优先"只是排序、Tomcat 在 refresh 中途启动、this 调用绕过代理)。三种自我感觉,对应三种假象,读到时请停下来:

· "我读得很顺":这是熟悉感,不是掌握。名词眼熟 ≠ 你能说出 BeanFactoryPostProcessor 和 BeanPostProcessor 改的是蓝图还是实例。

· "我做题很快":多半因为题目是你刚读那段的复述。真正的检验是第 7 章那些"该用哪种注入""为什么这个注解没生效"的判别题。

· "我没卡壳":多半思路一直贴着正文滑行,没真正调动结构。每章的"想一想"请先停十秒、自己答,再展开。

E概念地图

SpringApplication.run() 应用入口 驱动 ApplicationContext.refresh() 固定 12 阶段流水线 · 全教程主线 ① 改蓝图 ② 加工实例 ③ onRefresh BeanFactoryPostProcessor 改 / 读 Bean 蓝图 BeanDefinition Bean 的"蓝图" 自动配置 @Conditional 按 classpath/Environment 注册 BeanPostProcessor 加工 Bean 实例 换成代理 代理 Proxy @Transactional / @Async Bean 实例 被代理包裹后入容器 内嵌 Tomcat refresh 中途即启动 DispatcherServlet 前控制器 · 派发请求 贯穿全程:Environment(有序 PropertySource)→ @ConfigurationProperties 绑定 现代栈:可观测性 · 虚拟线程 · AOT·原生镜像 · Spring AI 章节顺序:01 容器 → 02 启动 → 03 自动配置 → 04 AOP → 05 Web·配置 → 06 现代栈
图 0Spring Boot 的核心拓扑:run() 驱动 refresh(),refresh 按固定顺序分三条轨道展开。注意三件事:① 改蓝图(BeanFactoryPostProcessor,含自动配置)和 加工实例(BeanPostProcessor,含代理替换)是两类不同的钩子,区分它们是理解一切机制的第一刀;② 红色那条——BeanPostProcessor 把 Bean 换成代理——是 @Transactional 等注解的真身,也是它们"不生效"问题的根源;③ 内嵌 Tomcat 在 refresh 中途启动,不是容器就绪之后。全教程沿这张图逐块下探。

F学习路径建议

顶部那条面包屑(00 → 01 → 02 → 03 → 04 → 05 → 06 → 07)是默认顺序:容器 → 启动流水线 → 自动配置 → AOP/代理 → Web/配置 → 现代栈 → 自测。按你的目的可以走支线:

  • 只想懂机制按顺序读 01 → 02 → 03 → 04,这四章是"魔法还原"的主干;05、06 可按需取用,最后用 07 的判别题检验。
  • 面试进阶重点 02(启动流水线时序)、03(自动配置生效机制 + "用户优先"为何只是排序)、04(代理与 self-invocation 根因)——这三处是高频追问,配 07 的原理层题。
  • 读他人代码/选型先读 01 的"一句话本质" + 03(看懂陌生 starter 怎么装配)+ 06(Spring vs Quarkus/Micronaut、虚拟线程、原生镜像选型轴)+ 07 的场景判别题。
  • 排查启动报错02(refresh 哪一步崩)+ 03(条件没命中 / Bean 没注册)+ 04(注解不生效)——三章覆盖了绝大多数"启动就炸"和"运行时静默失效"。

G目录

H学完之后

这份教程把"Spring Boot 容器的内部结构"装进你的 schema 后,下一步可以往这几个方向接:

  • 数据访问与事务底层:把第 4 章的代理事务接到 PlatformTransactionManager、传播级别、隔离级别上——同系列可参考 PostgreSQL 与 Redis 教程(缓存抽象的底层)。
  • 把服务接进 Agent:Spring AI 把 LLM、向量库、工具调用接进同一套容器与自动配置模型——第 6 章点到,可顺到 MCP 教程 与 工具调用教程。
  • 消息与分布式:spring-boot-starter-kafka 等 starter 正是第 3 章自动配置机制的实例——接 Kafka 与 Nacos 教程。
  • 原生镜像实战:拿第 6 章的 AOT / GraalVM 机制,给一个真实服务构建原生镜像,观察反射注册与闭世界约束。