《Spring Boot 高级》目录

《Spring Boot 高级》全书导航页:说明本卷面向已经能独立交付服务、想理解框架内部机制的读者,给出三条学习路径与一份八周计划,讲清四个部分之间的依赖关系,并按部分列出 11 章 33 节的完整索引,每一节都配一句话说明,另含面向排查场景的常见问题速查表,方便按需跳读与随时查阅。

《Spring Boot 高级》目录

这一页是全书的入口。它不只列出 33 节的标题,还给出三条可以照着走的阅读路径、每一节的一句话说明,以及一张按排查场景索引的常见问题速查表。如果你不确定从哪开始,先读「本书定位」与「读者画像」;如果你已经带着一个具体问题来,直接跳到「常见问题速查」或「分部分章节」按编号定位。

全书结构是:正文 11 章 33 节 + 目录 1 篇,共 34 篇。正文按「从容器内部到交付运行」的顺序分为四个部分:先拆开容器与装配机制,再看 Web 请求怎么被处理,接着进入数据、事务与安全,最后落到构建产物、可观测性与版本迁移。

如何使用本目录

这一页有三种用法,取决于你此刻的状态。

如果你准备系统读一遍,按顺序读「本书定位」「读者画像」「学习路径」三节,用十分钟决定自己的入口。高级卷与实战卷的差别在于:实战卷回答「这么配能跑、为什么这么选」,本卷回答「框架内部是怎么实现的」。如果你还没独立交付过一个服务,建议先读实战卷——本卷的很多结论要落在具体工程决策上才有意义。

如果你已经带着问题来,直接看「常见问题速查」。它按排查场景组织,每条给出简短回答与对应章节,定位到章节后再顺着那节的「小结」补齐背景,通常比通读整章更快。

如果你在核对某个具体机制,用「分部分章节」的表格按编号定位。每一行都有一句话说明,写清那一节讲什么、回答哪个问题,可以帮你确认是不是要找的那一节。

三种用法之外还有一种:把这一页当索引页长期放在收藏夹里。本卷 33 节分布在 11 章中,章节编号即定位坐标,表格里的每一行都可以直接点进去。当你已经读过一遍、只需要偶尔回查某个机制时,用这一页跳转通常比用站点搜索更快。

本书定位

这是一本面向已经能独立交付服务、想理解框架内部机制的工程师的书。它不教你怎么写一个 Controller,也不教你怎么配连接池——那些在入门卷与实战卷里已经讲过。它回答的是更靠里的一层问题:SpringApplication.run() 之后容器按什么顺序做了什么、自动配置类是怎么被挑出来的、一个 @Transactional 方法在字节码层面被织进了什么、请求从进入容器到返回响应经过了哪些组件。

它有三个刻意的取舍。

第一,每条结论都尽量落到可核实的证据上。书中大量结论来自对 4.1.1 实际 jar 的反编译核实(javap、unzip)与官方源码,而不是「我记得是这样」。凡是无法在本机核实的部分——原生镜像的构建产物、Kubernetes 与可观测性后端的运行输出、async-profiler 的火焰图——正文一律显式标注为「示例输出」,并给出你自己验证的步骤。

第二,只讲那些能改变你做法的机制。框架内部细节无穷无尽,本卷不追求穷举。挑选标准是:知道之后能解释一个常见现象、能定位一类线上问题、或者能在两个方案之间做出有依据的选择。纯粹的实现细节会被略过,或者压缩成一句「这里不必展开」。

第三,把「为什么这样设计」与「知道之后能做什么」并列。每一节都尽量回答三个问题:框架内部怎么做、为什么这样设计、知道这件事之后你能做什么。只讲机制而不讲用途,读起来会变成背源码。

如果你需要的是一份「照着配就能跑」的参考手册,实战卷更合适;如果你希望下次遇到「这个注解为什么不生效」「这个 bean 为什么初始化了两次」时能自己定位到具体机制,那本卷的深度是合适的。

与入门卷、实战卷的关系

三部曲不是三个独立话题,而是同一条能力线上的三个高度。理解它们的边界,能帮你判断某个问题该去哪一卷找答案。

维度入门卷实战卷本卷(高级)
回答的问题怎么用怎么选、代价是什么内部怎么实现
典型内容注解语义、配置项、起步依赖模块划分、缓存一致性、连接池调优、部署回滚refresh() 步骤、代理边界、事务同步、AOT 处理
读完能做什么写出可运行的服务交付可维护、可上线的服务定位机制类问题、在方案之间做有依据的取舍
前置依赖无入门卷入门卷 + 实战卷

三卷之间存在大量交叉引用,但每一卷都自成闭环:本卷不假设你记得实战卷里的某个具体配置,需要用到时会重新交代背景;实战卷也不假设你读过本卷,涉及内部机制时会给出「详见高级卷某节」的指引。因此你不必按顺序读三卷,也可以直接进本卷。

判断一个问题属于哪一卷,标准很简单:答案会不会随框架版本变化。会变的属于用法——某个配置项叫什么、某个 starter 的坐标是什么、某个版本的默认值是多少——这些在入门卷与实战卷。不变的是机制——容器按什么顺序启动、代理在什么条件下失效、事务同步回调在哪个阶段触发——这些在本卷,而且换个框架版本仍然成立。

怎么自己核实书中的结论

本卷的结论密度比较高,光靠记忆容易混。正文里凡是可以核实的结论,都给了核实方法;下面把最常用的几种集中列一遍,方便你在读每一节时随手验一遍。

查类的真实包路径与结构:用 javap。Spring Boot 4.x 做了模块化拆分,很多类换了模块甚至换了包,凭 3.x 的记忆写 import 会直接编译失败。拿到 jar 之后 unzip -l 看有哪些类、javap -p -c 看方法与字节码,比查文档更可靠。

查配置属性的真实名称:解压 spring-boot-*-4.1.1.jar 里的 META-INF/spring-configuration-metadata.json,属性名、类型、默认值、废弃状态都在里面。文档与代码不一致时以元数据为准。

查自动配置清单:看 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports,里面列出的才是真正会被加载的自动配置类。很多「我写了自动配置类但没生效」的问题,根因就是没有出现在这个文件里。

查运行时实际装配了什么:用 --debug 或 logging.level.org.springframework.boot.autoconfigure=DEBUG 打印条件评估报告,能直接看到哪些配置类被应用、哪些被条件挡下、挡下它的条件是什么。

查请求处理链与过滤器链:Security 用 @EnableWebSecurity(debug=true) 打印实际的过滤器链顺序;MVC 用日志或断点看 HandlerMapping 与 HandlerAdapter 的选择结果。

这些手段的共同点是:不依赖记忆,也不依赖文档版本。本卷鼓励你在读每一节时都动手验一次,这既是确认书中结论的方式,也是把机制变成自己判断力的方式。

读者画像

不同类型的读者,起点和建议入口差别很大。先在下面找到最接近自己的那一类。

① 读过入门卷与实战卷、想补齐原理的工程师。这是本卷的目标读者。建议从第 1 章顺序读到第 11 章。第一部分(第 1–3 章,容器内部机制)是全书的地基,后面每一章都会用到它;第二部分(第 4–5 章)与第三部分(第 6–8 章)是主体;第四部分(第 9–11 章)按需取舍。

② 正在排查一个具体问题的工程师。你不需要按顺序读。代理失效、循环依赖、@Transactional 不回滚、连接被提前占用、过滤器顺序不对——这些在「常见问题速查」里都有入口,定位到章节后读那一节即可。这类读者通常收获最直接,因为问题本身就是理解机制的最好切口。

③ 准备做 3.x → 4.x 迁移的工程师。建议先读第 11 章(迁移线集中在这里),再回头补第 1–2 章的容器与自动配置机制——4.x 的模块化重构会直接改变你写 import 与声明依赖的方式,不理解机制就只能照抄迁移清单。

④ 想理解响应式与虚拟线程这类新范式的开发者。直接读第 5 章(WebFlux 与 Reactor)与第 7.2 节(虚拟线程)。这两处是 4.x 与 3.x 差别最明显、也最容易凭印象写错的地方,书中对每条结论都标注了版本边界与核实方式。

学习路径

下表给出三条典型路径。三条路径不互斥,可以先跳读救急,再回头补齐。

路径适合谁读哪些预计用时
完整通读读过前两卷、想系统补齐原理第 1 章至第 11 章顺序读,每节配合 jar 核实7–9 周(每天 1 小时)
按问题跳读手上正有具体问题待排查按「常见问题速查」入口选:3.3、1.3、7.3、6.3、8.1、2.3 等2–3 周
迁移优先准备 3.x → 4.x 迁移11.1 → 11.2 → 11.3,再补 1.1、2.11–2 周

按问题跳读这条路径的入口不是章节顺序,而是你此刻遇到的现象:注解不生效看 3.3,循环依赖报错看 1.3,线程池被撑爆看 7.3,连接在方法一开始就被占用看 6.3,过滤器顺序不对看 8.1,自定义自动配置没生效看 2.3。每一节都自成闭环,但都会引用相关章节,读完后可以顺着引用补齐。

一份可执行的八周计划

上面三条路径偏原则。如果你希望有一份可以直接照着打勾的安排,下面这份八周计划可以作为起点(按每天投入一小时估算),它对应的是「完整通读」路径。

周次主要任务完成标志
第 1 周第 1 章:启动流程、Bean 定义、依赖解析与循环依赖能画出 refresh() 的主要步骤并说出断点位置
第 2 周第 2–3 章:自动配置与条件装配、AOP 与代理能解释自定义自动配置为什么没生效、注解为什么被绕过
第 3 周第 4 章:MVC 处理链、参数解析与消息转换、异常解析能说清一次请求经过哪些组件、异常被谁接住
第 4 周第 5 章:Reactor 与背压、WebFlux 处理、阻塞隔离能判断一段代码该不该放进 boundedElastic
第 5 周第 6 章:持久化上下文、Flush 时机、连接与延迟加载能解释连接何时被占用、延迟加载为何抛异常
第 6 周第 7 章:事务同步与事件、虚拟线程、线程池模型能说清事务提交后发消息该怎么写、pinning 何时发生
第 7 周第 8 章:过滤器链、认证授权流程、方法安全与传播能读懂 debug 模式的过滤器链并定位越权问题
第 8 周第 9–11 章:AOT 与原生镜像、可观测性机制、迁移能判断服务适不适合上原生镜像、能列出迁移步骤

这份计划的关键不在于准时,而在于每一周都有一处可以动手核实的机制。高级卷的内容光读记不住,配合 javap、unzip、--debug、JFR 这些手段自己验一遍,印象才会留下来。

版本与示例约定

本卷所有结论以 Spring Boot 4.1.1 + Java 21(Temurin 21.0.12.1) 为基线,构建工具为 Maven 3.9.12,对照线为 Spring Boot 3.5.16。凡 3.5.x 与 4.1.x 行为不同之处,正文会两版分别标注;凡涉及版本边界(例如虚拟线程的 pinning 行为在 JDK 21 与 JDK 24 不同)也会显式说明。

本机没有的东西:GraalVM 的 native-image、Kubernetes 集群、Prometheus / Jaeger / Zipkin 后端、async-profiler。涉及这些工具或后端的构建日志、运行输出、界面截图、火焰图,正文一律标注为「示例输出」,并给出你在自己环境里复现的步骤。只有纯 Spring Boot 应用的启动、构建,以及 JDK 自带的 jcmd / jfr / jstack 输出,才引用本机实测数据。

性能相关的数字只给量级与测量方法,不给出未经实测的精确值。要数字的地方,正文给的是「怎么测出这个数字」的步骤,而不是一个拍脑袋的结果。

四个部分之间的依赖关系

正文按「从容器内部到交付运行」的顺序分为四个部分,它们之间是递进关系:

部分章节回答什么问题依赖谁
第一部分 容器内部机制第 1–3 章容器怎么启动、Bean 从哪来、注解怎么被织进去无
第二部分 Web 请求处理第 4–5 章一次请求经过哪些组件、响应式栈有何不同第一部分
第三部分 数据、事务与安全第 6–8 章持久化上下文与连接怎么流转、鉴权在哪个环节生效第一部分、第二部分
第四部分 构建、可观测与迁移第 9–11 章构建期做了什么、运行期怎么看、怎么从 3.x 迁过来前三部分全部

第一部分是全书的地基,不能跳。第 1–3 章讲的是容器启动、自动配置装配与代理机制,后面每一章都会用到。尤其是第 3 章的代理机制——不理解它,@Transactional 失效、@Async 不生效、@Cacheable 没起作用这些现象都只能靠记结论。

第二部分与第三部分是主体。Web 请求处理(第 4–5 章)覆盖 MVC 管线与响应式栈;数据、事务与安全(第 6–8 章)覆盖持久化上下文、事务同步、虚拟线程、过滤器链与授权。这两部分合计 5 章 15 节,是最接近日常排查场景的内容。

第四部分按需取舍。第 9 章(AOT 与原生镜像)如果你不上原生镜像可以快读;第 10 章(可观测性机制)建议至少读完 10.1 与 10.3;第 11 章(迁移)如果你还在 3.x 上,则应当优先读。

可以跳读的是部分章节。第 5 章(WebFlux)如果你不做响应式可以跳过;第 9.2、9.3 如果不碰原生镜像可以只读 9.1 了解 AOT 处理;但第 1–3 章、第 6 章、第 7.1 与 7.3 属于几乎所有服务都会碰到的内容,建议不要跳过。

分部分章节

下面按部分列出全部 33 节。每一行都有一句话说明,写清那一节回答什么问题,用来帮你确认这是不是你要找的那一节。

第一部分:容器内部机制(第 1–3 章)

这一部分拆开 Spring 容器的三个核心机制:启动流程、自动配置装配、代理。读完能解释大部分「明明配了却不生效」的现象。

编号章节说明
1.1ApplicationContext 启动流程从 SpringApplication.run() 追到容器可用,拆开 refresh() 的各个步骤,标出两类后处理器的介入时机与断点位置
1.2Bean 定义注册与合并讲清 BeanDefinition 的结构、组件扫描如何产出定义、父子定义的合并规则,以及同名定义冲突时谁赢
1.3依赖解析与循环依赖走一遍 getBean() 的解析流程,解释三级缓存为什么能解掉 setter 循环依赖、构造器注入为什么必然失败
2.1自动配置类的加载顺序4.x 的 imports 文件里有多少条、@AutoConfiguration 的语义,以及排序靠什么决定、为什么要有字典序兜底
2.2@Conditional 家族实现条件是在哪个阶段被评估的、OnClassCondition 这类实现怎么工作,以及评估结果如何进 --debug 报告
2.3自动配置的覆盖与排除自动配置如何为用户定义「让路」、两种排除方式的差别,以及覆盖自动配置 Bean 的几种做法与风险
3.1JDK 动态代理与 CGLIB两种代理的选择规则到底是什么、proxyTargetClass 如何改变结果,以及 CGLIB 内联进 spring-core 后的影响
3.2切面织入与顺序@Aspect 如何变成 Advisor、多个 advice 如何串成调用链,以及 @Order 与同切面内 advice 的相对次序
3.3代理失效的边界自调用、private / final / static 方法为什么绕过代理,以及 AopContext.currentProxy() 与自注入两种解法的代价

第二部分:Web 请求处理(第 4–5 章)

这一部分处理「一次请求进来之后发生了什么」,并对照讲清响应式栈与阻塞栈的根本差异。

编号章节说明
4.1DispatcherServlet 处理链逐段拆开 doDispatch(),讲清 HandlerMapping 如何找到 handler、HandlerAdapter 这一层为什么存在
4.2参数解析与消息转换参数解析器的默认顺序、@RequestBody 如何按 Content-Type 选中消息转换器,以及自定义的注册位置
4.3过滤器、拦截器与异常解析Filter 与 Interceptor 的执行时机差异、异常解析链的固定顺序,以及 @ResponseStatus 在哪一环被处理
5.1响应式类型与背压Mono / Flux 的语义与惰性、Reactive Streams 的 request(n) 协议如何构成背压,以及各种背压策略的适用场景
5.2WebFlux 请求处理WebFlux 与 MVC 是两条独立栈、DispatcherHandler 与 WebFilter 的职责,以及函数式端点与注解式端点的取舍
5.3阻塞代码的隔离在事件循环线程上跑阻塞代码会发生什么、publishOn 与 subscribeOn 的差别,以及如何用 BlockHound 把问题抓出来

第三部分:数据、事务与安全(第 6–8 章)

这一部分覆盖最容易出线上问题的三块:持久化上下文与连接、事务与线程模型、认证与授权。

编号章节说明
6.1EntityManager 与持久化上下文注入的 EntityManager 为什么是个代理、实体的四种状态如何转换,以及持久化上下文何时创建与销毁
6.2事务与 Flush 时机Hibernate 在哪些时刻 flush、FlushMode 各取值的含义,以及 readOnly 在 ORM 层实际改变了什么
6.3连接获取与延迟加载一次事务里连接何时被占用与归还、LazyConnectionDataSourceProxy 的意义,以及 open-in-view 的代价
7.1事务同步与事件TransactionSynchronizationManager 的机制、@TransactionalEventListener 四个 phase 的语义,以及提交后发消息为什么靠它
7.2虚拟线程下的 Spring开启虚拟线程后框架替换了哪些组件、synchronized 导致的 pinning 在哪个 JDK 版本被修掉,以及它适合什么任务
7.3并发编程与线程池模型ThreadPoolTaskExecutor 的队列策略、@Async 默认执行器为什么危险,以及上下文如何跨线程传递
8.1过滤器链构建过程springSecurityFilterChain 是怎么被创建并注册的、HttpSecurity 的 DSL 装配出什么,以及多个链如何匹配
8.2认证与授权流程ProviderManager 与认证提供者的协作、SecurityContext 的存储与保存策略,以及授权决策链怎么走
8.3方法安全与上下文传播@EnableMethodSecurity 背后仍是 AOP、表达式求值拿到哪些上下文,以及安全上下文如何跨线程传播

第四部分:构建、可观测与迁移(第 9–11 章)

这一部分讲构建期与运行期各自发生了什么,最后落到 3.x → 4.x 的迁移。

编号章节说明
9.1AOT 处理与生成物AOT 处理在构建期做了什么、生成物有哪些、扩展点是什么,以及 AOT 模式下容器为什么能少走反射
9.2反射与资源配置反射与动态代理在原生镜像下为什么失败、RuntimeHints 如何声明元数据,以及排查配置缺失的手段
9.3原生镜像的构建与权衡原生镜像换来什么、付出什么代价、哪类服务适合上,以及它与 CDS 等手段的关系
10.1Micrometer 指标模型四种计量器的语义差异、Observation 如何统一指标与追踪、MeterFilter 能做什么,以及 P99 怎么才算对
10.2分布式追踪实现追踪门面为什么这样设计、桥接实现的取舍、采样策略如何组合,以及传播格式的差别
10.3生产问题诊断手段JFR 记录什么、jcmd 与线程转储怎么用、堆转储怎么获取与分析,以及在线诊断工具的风险
11.1Spring Boot 4 的模块化重构大模块被拆成了什么、starter 改名对照,以及这对依赖声明与 import 语句的实际影响
11.2依赖与配置迁移清单按依赖关系排好序的迁移步骤:坐标与版本、类与注解改名、配置属性重命名,以及每一步怎么验证
11.3迁移实测与回滚策略迁移时如何分批验证、哪些改动不可回滚、怎么用特性开关降低风险,以及什么情况下不该迁

常见问题速查

下面这些是排查时最常碰到的现象,先在这里给出简短回答,详细机制展开在对应章节。回答只给方向,具体步骤请到对应章节查。

现象简短回答详见
同类里调自己的 @Transactional 方法,事务没生效?自调用绕过了代理,方法上的注解根本没被拦截到;改用自注入或 AopContext.currentProxy()3.3
启动时报循环依赖错误?构造器注入的循环依赖无法用三级缓存解决,只能靠重构、@Lazy 或 ObjectProvider 破环1.3
自定义的自动配置类没生效?先看它有没有被 AutoConfiguration.imports 登记,再看条件是否满足、是否被用户定义「劝退」2.3
@Async 方法同步执行了?同样是自调用绕过代理;另外要确认默认执行器是否被换成有界线程池3.3、7.3
线程池队列无限增长最后 OOM?ThreadPoolTaskExecutor 的队列容量默认无界,max-size 形同虚设,必须显式设 queue-capacity7.3
事务方法一开始连接就被占满了?显式隔离级别或 readOnly 会让事务开始时即取物理连接;默认设置下连接在首条 SQL 时才取6.3
@TransactionalEventListener 不触发?检查 phase 与是否有活动事务,非事务上下文下需要 fallbackExecution7.1
延迟加载抛 LazyInitializationException?持久化上下文已关闭;用 JOIN FETCH / @EntityGraph 取够数据,而不是靠延长 open-in-view6.3
Security 过滤器顺序不对、自定义 Filter 位置奇怪?用 @EnableWebSecurity(debug=true) 打印实际链,按 FilterOrderRegistration 的登记次序定位8.1
方法级权限注解没拦住请求?确认 @EnableMethodSecurity 已开、表达式写对,并注意它同样受代理边界限制8.3
想确认某个类在 4.x 的包路径变了没有?用 javap / unzip 直接查 jar,不要凭 3.x 的记忆写 import11.1、11.2
不确定某段结论是不是本机实测?涉及原生镜像、K8s、可观测性后端、async-profiler 的一律是「示例输出」,正文有显式标注9.1–9.3、10.1–10.2

读完本卷之后

本卷覆盖的是 Spring Boot 的框架内部机制。读完之后,下面这些方向可以作为下一步。

如果想补齐工程交付能力,读实战卷。它讲模块拆分、依赖治理、测试分层、缓存一致性、连接池调优、容器化部署与上线回滚——本卷回答「框架内部怎么实现」,实战卷回答「生产上怎么选、代价是什么」。

如果需要查阅专题级深度,站内专题与本书是互补关系:本书是「按机制层次走一遍」,专题是「按主题深挖」。

小结

这一页给出了全书的地图:34 篇的组织方式、四类读者的入口、三条阅读路径与一份八周计划、四个部分之间的依赖关系,以及 33 节的逐节索引与排查速查表。

如果你现在还不确定从哪开始,最稳妥的做法是:从第 1 章第 1 节开始,按顺序读,并且每一节都用 javap、unzip 或 --debug 亲手验一遍。高级卷的结论只有自己核实过才会变成判断力;只是读过一遍的机制描述,遇到真问题时还是想不起来。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「java」更多文章

  1. 《Spring Boot 入门》18.3 打包与运行
  2. 《Spring Boot 入门》18.2 实现
  3. 《Spring Boot 入门》18.1 需求与设计