《Spring Boot 入门》11.2 CORS 跨域
前端从 5173 端口调用 8080 的图书接口,浏览器报跨域,可服务端日志里请求明明到了。本节讲清同源策略拦的到底是谁、简单请求与预检请求的区别,贴出真实的 OPTIONS 预检头,演示 @CrossOrigin、addCorsMappings、CorsFilter 三种配置,并说透 allowedOriginPatterns 与 allowCredentials 的坑。
category
前端从 5173 端口调用 8080 的图书接口,浏览器报跨域,可服务端日志里请求明明到了。本节讲清同源策略拦的到底是谁、简单请求与预检请求的区别,贴出真实的 OPTIONS 预检头,演示 @CrossOrigin、addCorsMappings、CorsFilter 三种配置,并说透 allowedOriginPatterns 与 allowCredentials 的坑。
本节区分契约测试与集成测试的边界,说明消费者驱动契约在 Spring Cloud Contract 与 Pact 之间的选型,并给出数据隔离三策略(事务回滚、@Sql、每测试独立 schema/容器)的对比、测试数据构造规范,以及 @DirtiesContext 的真实代价。
本节解释内嵌 H2 为何会掩盖 PostgreSQL 方言差异,给出 Testcontainers 2.0 在 Spring Boot 4.x 下的依赖坐标、@ServiceConnection 用法与共享容器模式,讲清容器复用、CI 里 Docker 的可用性前提,并附镜像拉取、端口、健康检查三类失败的排查清单。
本节用图书借阅服务的借阅流程,把单元、切片、集成、端到端四层测试的成本与收益逐项拆开,给出各层配比与 CI 分阶段执行命令,并对齐 Spring Boot 4.x 的测试注解口径(@MockitoBean、RestTestClient、@AutoConfigureMockMvc),最后讲清测试并行与上下文缓存的取舍。
图书服务要加一个管理页面,HTML、CSS、JS 与封面图该放哪、用什么 URL 访问?本节讲清 Spring Boot 四个默认静态资源目录及优先级、默认 /** 映射规则,区分 static-locations 与 static-path-pattern,并演示自定义映射、缓存控制与内容哈希指纹,最后说清静态资源与接口路径冲突时谁优先。
本节权衡配置中心的收益与代价,比较 Spring Cloud Config、Nacos、Apollo 的定位差异,讲清 @RefreshScope 与 @ConfigurationProperties 在刷新行为上的关键区别,并给出刷新风暴、灰度发布与配置中心不可用时的降级策略。
本节从口令泄露的真实路径讲起:Git 历史、镜像层、进程参数、/proc 与日志各是怎么漏的;再比较环境变量与挂载文件的取舍,划清 Jasypt 这类加密方案的适用边界,给出 Vault / KMS / K8s Secret 的接入方式与密钥轮换对连接池、签名校验的实际影响。
入门卷讲过 application.yml 与 profile,本节解决生产上真正棘手的问题:环境维度如何划分、profile 组合与 group 怎么用、jar 内基线与外部覆盖如何分层、12-Factor 下哪些值该进环境变量,以及 spring.config.import 的组合语法与 4.1 新增的 encoding 参数。
设计一个 ApiResponse<T> 包装体,用 ResponseBodyAdvice 自动包装成功响应并避开泛型擦除与 String 转换器的坑,同时讨论统一响应体的代价——与 HTTP 状态码语义重复、对第三方客户端不友好、文件下载与 204 的例外,给出该用与不该用的判断依据,并输出一套完整实现与 curl 实测响应。
本节讲 Maven 构建加速:先给出定位慢在哪里的步骤,再逐项拆解跳过无用阶段、按模块增量构建、并行构建、依赖预拉与离线、CI 缓存本地仓库、镜像源与增量编译等手段,重点说明 4.1 中 -DskipTests 不再跳过测试 AOT 处理这一语义变化及替代写法。
本节讲 Spring Boot 多模块工程的版本对齐:对比 spring-boot-starter-parent 与 spring-boot-dependencies BOM 的引入方式与取舍,说明 import scope 的生效规则、如何自建 BOM 统一内部组件版本、如何用 properties 或显式声明覆盖托管版本,并汇总 4.x 各依赖的大版本变化与 4.0 移除的依赖管理。
本节用图书借阅服务 book-loan 的五模块工程讲透 Maven 依赖冲突排查:从 NoSuchMethodError 等症状反查依赖树,读懂 dependency:tree 的 omitted 与 conflict 标记,掌握最短路径优先与先声明优先两条调解规则,并给出 exclusions、dependencyManagement 与 dependency:analyze 的用法。
把异常处理从各控制器集中一处,用 @ControllerAdvice 与 @RestControllerAdvice 做全局处理,并用 basePackages、assignableTypes 等限定范围。还会改写框架内置异常(校验、JSON 解析、405、404),用 @Order 排优先级,并借 ResponseEntityExceptionHandler 统一内置异常响应。
讲清按功能分包与按层分包的取舍,给出图书借阅服务「模块边界 + 模块内按层」的分包方案,演示用 package-private 收窄暴露面、约束模块间依赖方向,并用 ArchUnit 把「禁止循环依赖」「领域层保持纯净」等架构约束固化成会在 CI 上失败的测试。
讲清父 POM 的 parent 继承与 dependencyManagement 版本管理的分工,演示导入 spring-boot-dependencies BOM、子模块声明依赖、用 Enforcer 预防版本冲突,以及可复用库模块的打包与发布方式。
从团队规模、发布节奏、复用需求与编译耗时四个维度判断单体还是多模块,给出「先别拆」的五条红线与「该拆了」的信号,对比按层、按业务、按可复用库三种拆分粒度各自的代价与适用场景,并附一份可在评审会上直接使用的决策清单与三个常见误区,以及判断时常被忽略的隐性维护成本。
Spring Boot 默认的错误响应由 BasicErrorController 生成,字段有限且不携带业务语义。本节先看清默认 JSON 长什么样,再讲 @ExceptionHandler 的用法与作用范围(只对所在控制器生效)、多异常与继承关系的匹配顺序、@ResponseStatus 与 ResponseEntity 的状态码控制,并说明为什么在每个控制器里重复写处理方法是不可持续的。
《Spring Boot 实战》全书导航页:说明本卷面向已会用 Spring Boot、但没独立交付过生产服务的工程师这一读者定位,给出三条学习路径与一份十周计划,讲清四个部分之间的依赖关系,并按部分列出 18 章 54 节的完整索引,另含生产场景常见问题速查表,每一节都配一句话说明,方便按需跳读与随时查阅。
同一个 DTO 在新增和修改时规则常常冲突:新增时 id 必须为空,修改时 id 必须非空。本节用图书 DTO 演示校验分组、@GroupSequence 组顺序、嵌套对象级联与集合元素校验,指出 @Valid 加错位置会静默跳过的陷阱,并以一个新增/修改共用 DTO 的完整示例收尾。
标准注解不够用时,就要自己写约束。本节以 ISBN 格式校验为例,完整演示自定义注解 + ConstraintValidator 实现,拆解 message、groups、payload 三个成员,讲清 ValidationMessages.properties 的中文国际化与 4.x 的编码要求,并给出在 Service 层手动触发校验的两种方式与真实异常响应。