《Spring Boot 实战》8.2 Redis 缓存实践
把图书借阅服务的缓存落到 Redis:接入 starter、选序列化方案并厘清与 4.x Jackson 3 的关系、Lettuce 共享连接与 Jedis 池的取舍、键命名与内存估算、大 key 与热 key 的危害,以及 4.1 新增的 @RedisListener 自动配置。
category
把图书借阅服务的缓存落到 Redis:接入 starter、选序列化方案并厘清与 4.x Jackson 3 的关系、Lettuce 共享连接与 Jedis 池的取舍、键命名与内存估算、大 key 与热 key 的危害,以及 4.1 新增的 @RedisListener 自动配置。
把缓存声明式地加到图书借阅服务上:讲清 @Cacheable / @CachePut / @CacheEvict / @Caching 的语义差异、key 与 SpEL 的写法陷阱、condition 与 unless 的执行时机、CacheManager 与多级缓存配置,以及同类内部调用失效和 TTL 表达边界。
本节把 record 版 Book 改造成 JPA 实体:讲透 @Entity、@Id、@GeneratedValue、@Column、@Table 与主键生成策略的取舍,说清为什么实体不能用 record 而 record 适合做 DTO,梳理 CrudRepository 与 JpaRepository 的继承关系,并给出实体 equals/hashCode 的可靠写法。
对比 URL、Header、媒体类型三种版本载体的取舍,讲清 Spring Boot 4 内置 API Versioning 的 spring.mvc.apiversion.* 属性、@GetMapping(version=...) 注解与 ApiVersionConfigurer 精细控制,给出向后兼容判定清单、Deprecation/Sunset 废弃流程与破坏性变更的并行发布策略。
系统讲解 Java 日志体系:SLF4J 门面、Logback/Log4j2 实现、日志级别与布局、MDC 与链路追踪、异步日志与性能、结构化日志、日志轮转与采集,以及统一日志规范与踩坑避坑。
系统讲解 Java 异常体系与防御式编程:异常层次与选择、checked/unchecked 取舍、try-with-resources 与资源释放、异常日志与链路追踪、Optional 与早期失败,并用实战场景演示健壮代码写法。
把 OpenAPI 文件从代码的产物变成代码的输入:用 openapi-generator 7.26 生成接口与 DTO,用 interfaceOnly 与生成目录划清生成与手写的边界,给出避免重生成覆盖业务逻辑的三条纪律,并在 CI 里用 validate、spectral、漂移检查与 oasdiff 四道关固定契约。
深入 JVM 类加载机制与字节码:双亲委派模型、类加载器体系、字节码文件结构、Javassist/ASM 运行时字节码增强、Arthas/JFR 诊断,以及 SPI 打破双亲委派与热更新原理。
系统讲解 Java 网络编程:BIO/NIO/AIO 三种模型、Socket/ServerSocket 编程、NIO Channel-Buffer-Selector 三角色、零拷贝与堆外内存、java.net.http.HttpClient、WebSocket 客户端,以及高并发 IO 模型选型。
深入 Java 集合框架底层:ArrayList/LinkedList 扩容机制、HashMap 与红黑树、ConcurrentHashMap 锁分段与 CAS、CopyOnWriteArrayList、队列家族与并发容器选型,以及迭代器 fail-fast 原理与工程选型指南。
深入 Java 泛型与反射机制:类型擦除与桥方法、PECS 通配符、Type 体系、反射 API 全解析、动态代理与 CGLIB、注解处理与代码生成,以及反射性能优化与安全考量。
讲清 Spring Boot 4 下 springdoc-openapi 3.x 的依赖坐标与版本线,用 @Operation、@Schema、@ApiResponse 补齐接口语义,划清推断与注解的边界,用 GroupedOpenApi 拆分前台与后台文档,并给出生产环境关闭文档或加鉴权的两种收口方式与四类常见坑。
本节把图书管理服务从内存 Map 换到真正的数据库:引入 spring-boot-starter-data-jpa 与 H2、MySQL 驱动,逐项讲清 spring.datasource.* 与 HikariCP 关键参数的默认值,用表格对比 ddl-auto 四个取值的风险,并演示 4.1 新增的惰性连接获取与启动期连不上库的真实报错。
N+1 是 JPA 生产事故的头号来源。本节从 SQL 日志里还原 N+1 的形态,对比 JOIN FETCH、@EntityGraph 与 @BatchSize 三种抓取策略的代价,讲清分页叠加 fetch join 的经典陷阱与 LazyInitializationException 的根因,并给出定位与验收方法。
派生查询、@Query(JPQL / native)与 Criteria、Querydsl 各有适用边界。本节用图书借阅服务的多条件检索场景对比三种写法的可维护性与类型安全,给出动态条件查询的落地方式、原生 SQL 的方言锁定代价,以及 4.x 下 Hibernate 7.x 的相关口径。
实体直接出现在接口层会带来懒加载代理序列化失败、字段泄露与循环引用三类事故。本节给出投影(interface / DTO)的用法与边界、手写转换与 MapStruct 的取舍、Repository 与 Service 的职责划分,以及 readOnly 事务与转换时机的关系。
每个接口都要记日志、查登录,写进 Controller 太啰嗦。本节对比 Filter(Servlet 规范)与 HandlerInterceptor(Spring MVC)的执行时机,用真实日志证明 Filter → Interceptor → Controller 的顺序,演示两种 Filter 注册方式与拦截器路径匹配,并完整实现请求 ID 贯穿与登录校验。
讲清 POST 为什么需要幂等键、幂等键的三种实现(唯一索引 / Redis 去重 / 状态机)各自的可靠性边界、乐观锁与 If-Match/ETag 的条件请求写法、并发写冲突用 409 还是 412 的取舍与重试语义,以及限流与防重各自解决什么问题。
围绕借阅服务的列表接口,讲清 Pageable 与 Page/Slice 的取舍、count 查询的真实代价、偏移分页的深分页问题与 keyset 分页的写法、过滤参数的表达方式、排序字段白名单如何同时防注入与防全表扫描,以及分页元信息的响应信封该怎么定。
把「图书借阅管理服务」的动作式接口重写成资源式接口:讲清资源命名的判据、URL 层级与扁平化的取舍、HTTP 方法与状态码的语义,以及批量操作、自定义动作和统一错误响应该在什么条件下破例,并给出可直接复用的 Controller 与 ProblemDetail 代码。