《Spring Boot 入门》9.1 Bean Validation 常用注解
本节讲清 Jakarta Validation 与 Hibernate Validator 9.0 的关系,演示如何用 spring-boot-starter-validation 给图书接口启用 @Valid,速查 @NotNull、@NotBlank、@NotEmpty 等常用注解,并贴出校验失败时的真实响应与 @Valid、@Validated 的区别。
category
本节讲清 Jakarta Validation 与 Hibernate Validator 9.0 的关系,演示如何用 spring-boot-starter-validation 给图书接口启用 @Valid,速查 @NotNull、@NotBlank、@NotEmpty 等常用注解,并贴出校验失败时的真实响应与 @Valid、@Validated 的区别。
本节把「图书管理服务」从随手写的接口改造成符合 REST 约定的一整套 API:资源如何命名、HTTP 方法与状态码怎样搭配、为什么幂等性决定重试策略、分页过滤排序如何与 Spring Data 的 Pageable 对齐、统一响应包装体值不值得用,以及 API 版本化的三种方式与 4.x 内建支持。
本节讲清控制器如何取出请求数据、又如何写回响应:六种取参方式(@PathVariable、@RequestParam、@RequestBody、@RequestHeader、@CookieValue、@ModelAttribute)的适用场景,@RequestBody 与 @ModelAttribute 的本质区别,四种返回类型的取舍,以及 Jackson 3 的包名与注解变化。
本节把「图书管理服务」的 HTTP 入口搭起来:分清 @Controller 与 @RestController(以及 @ResponseBody 的隐含关系),掌握 @RequestMapping 家族与类级、方法级路径拼接规则,用正则约束路径变量,并亲眼看到路径不匹配返回 404、HTTP 方法不匹配返回 405 的差别。最后演示 4.x 新增的 API Versioning 最小用法。
学会读 --debug 打印的自动配置报告:从 Positive/Negative matches、Exclusions、Unconditional classes 四段定位 bean 为何没生效,用 DataSource 实例逐层看 reason,再用 ConditionEvaluationReport、Actuator 端点与 IDE 断点把排查串起来,附症状速查表。
从零手写一个可发布的 acme-spring-boot-starter:完整 pom、配置属性类、客户端、@AutoConfiguration 自动配置类与 .imports 登记文件,配条件装配与排序保证不侵入宿主项目,再讲 mvn install、宿主验证、--debug 报告片段与七个常见错误。
从一行 spring-boot-starter-webmvc 出发,拆开一个 starter 的两块拼图——依赖聚合模块与自动配置模块,用 4.1.1 的真实依赖树讲清它到底拉了哪些 jar,再给出 4.0 模块化后的命名三段式、-test 测试模块约定、为什么 starter 不能带 @ComponentScan,以及按用途分类的官方 starter 一览表。
本节把配置源按官方 4.x 顺序完整排一遍,并用实测回答「同一个键在五处定义时谁生效」:先给出从命令行、环境变量到默认属性的优先级表,再讲环境变量的命名转换、占位符与 random 值、--key=value 与 -D 的区别,最后给出配置加密的思路与选型。
本节把 6.1 里的一整块配置绑成类型安全的 Java 对象:先对比 @ConfigurationProperties 与 @Value 的差别,再给出 record 与构造器绑定的写法(4.x 已无需 @ConstructorBinding),覆盖嵌套对象、List/Map 与松散绑定规则,最后用 @Validated 做校验并生成 IDE 补全元数据。
本节围绕「图书管理服务」的 dev/test/prod 三套配置展开:先对比 properties 与 yml 的取舍,再拆解 YAML 的缩进、冒号、隐式类型、多文档等六个常见坑;然后讲清 application-{profile}.yml 的命名、激活方式、@Profile 与组合表达式,最后用 spring.config.import 读取 .env 并介绍 4.1 的编码指定能力。
本节用图书缓存 BookCache 实测 Bean 从构造器到销毁的完整生命周期,用真实日志证明 @PostConstruct、InitializingBean、自定义 init-method 与 BeanPostProcessor 的执行顺序,并说明 SmartInitializingSingleton、ApplicationRunner 各自该用在什么时机。
本节用图书管理服务的 BookService 与 BookRepository 对比构造器、Setter、字段三种注入方式,解释官方为何推荐构造器注入,演示 @Qualifier 与 @Primary 解决同类型多 Bean,并拆解五种作用域与 prototype 注入 singleton 的经典陷阱及两种解法。
本节从一段手写 new 的代码讲起,说明 IoC 到底反转了什么,理清 ApplicationContext 与 BeanFactory 的关系,逐一演示 @Component、@Bean、@Import 把类变成 Bean 的三种方式,并用 getBeanDefinitionNames() 实测打印容器内容,帮你判断哪些类该交给容器、哪些不该。
逐个讲透 @ConditionalOnClass、@ConditionalOnMissingBean、@ConditionalOnProperty、@ConditionalOnWebApplication、@ConditionalOnBean 等条件注解,每类配一个最小可运行示例,并说明评估顺序的坑与如何用条件装配实现「按配置开关功能」。
顺着 @EnableAutoConfiguration 一路追到 AutoConfigurationImportSelector 与 AutoConfiguration.imports 清单文件,讲清 3.x/4.x 的加载路径、4.0 模块化后包名的迁移规律,并用 --debug 打印的自动配置报告解读 Positive/Negative matches。
从「我什么都没配,Tomcat 怎么就起来了」这个疑问出发,逐层拆开 @SpringBootApplication 背后的三个注解:@SpringBootConfiguration、@EnableAutoConfiguration 与 @ComponentScan,用等价代码验证,并给出包扫描与 exclude 的常见误用与排查方法。
用 mvn package 把 demo 打成可执行 jar,拆解 BOOT-INF/classes、BOOT-INF/lib 与 JarLauncher 的内部结构,讲清 4.0 移除可执行 jar 启动脚本、4.1 用 tools 取代 layertools 两条变更,并说明分层 jar 与 Docker 镜像的关系。
对比传统 war 部署与内嵌 Tomcat,拆解 SpringApplication.run() 的环境准备、容器创建、Bean 加载与服务器启动四步,逐行解读 4.1.1 真实启动日志,并给出端口占用、Bean 创建失败、依赖缺失三类常见启动问题的日志特征与排查方法。
在 demo 项目里写出第一个 REST 接口:用 @RestController 与 @GetMapping 暴露 /hello,对比返回字符串与返回对象自动 JSON 序列化的差别,掌握 @RequestParam 与 @PathVariable 两种取参方式,并用 curl 完成一次真实的请求与响应验证。
本节读懂 demo 项目:给出标准 Maven 目录树并解释各目录职责,逐行拆解启动类与 @SpringBootApplication、SpringApplication.run;重点讲包扫描规则,说明启动类为何必须放根包;再讲 application.properties 与 yml 的位置与优先级、.gitignore 建议,以及两种运行方式的差别。