其他
在 Spring Boot 3 中按功能包实现 DDD…
当你需要为 Spring Boot 3 服务创建基于 Spring Data JPA 的增删改查 REST 接口、领域聚合、仓储与 DTO 时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 47/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 51/100 ×0.15
适用场景
在 Spring Boot 3 中按功能通用
解决思路
- 建立功能结构:创建 feature/<name>/ 目录,包含 domain、application、presentation、infrastructure 子包;继续前先验证目录结构符合功能边界。
- 定义领域模型:创建实体类,通过工厂方法(create、update)强制不变量,保持领域逻辑不依赖框架;推进前先用单元测试覆盖所有不变量。
- 暴露领域端口:在 domain/repository 中声明仓储接口,描述持久化契约而不含实现细节;确认接口签名与领域操作一致。
- 提供基础设施适配器:在 infrastructure/persistence 中创建映射到领域模型的 JPA 实体,实现 Spring Data 仓储;运行 @DataJpaTest 验证实体映射与仓储集成。
- 实现应用服务:创建 @Transactional 服务类,编排领域操作与 DTO 映射;确保事务边界正确,并在需要处应用乐观锁。
- 定义 DTO 与控制器:使用 Java record 作为 API 契约并加 jakarta.validation 注解,映射 REST 端点并返回正确状态码;测试校验约束并验证 HTTP 状态码(POST 201、GET 200、DELETE 204)。
- 验证与部署:使用 Testcontainers 运行集成测试,验证迁移(Liquibase/Flyway)与聚合 schema 一致;部署前执行完整测试套件,确认 schema 迁移脚本已应用。
- 最佳实践:按聚合在功能包内共置 domain、application、presentation 代码;使用 Java record 作为不可变 DTO,在服务边界转换领域类型;写操作应用事务与乐观锁;规范化分页默认值(page、size、sort)并记录查询参数;以 info 级别记录 CRUD 生命周期事件(create、update、delete)并保留结构化审计轨迹;通过 Spring Boot Actuator 暴露健康与指标,监控吞吐量与错误率。
- 约束与警告:绝不在控制器中直接暴露 JPA 实体,以防懒加载泄漏与序列化问题;绝不混用字段注入与构造器注入,保持不可变性以便测试;绝不把业务逻辑嵌入控制器或仓储适配器,保持在 domain/application 层;始终积极校验输入,防止约束违规并产生一致的错误负载;始终确保迁移(Liquibase/Flyway)在部署 schema 变更前反映聚合演进;始终在合并前用 Testcontainers 运行集成测试,防止持久化回归。
- 参考:可查看 references/crud-reference.md(HTTP 方法、注解、DTO 模式)、references/examples-product-feature.md(从入门到进阶的渐进示例)、references/spring-official-docs.md(Spring Boot 官方文档);也可运行 python scripts/generate_crud_boilerplate.py --spec entity.json --package com.example.product --output ./generated 生成 CRUD 样板。
适用边界 · 注意事项
- 不使用 Spring Boot 3 或 Spring Data JPA 的项目
- 不需要 REST API 或数据库持久化的场景
- 无法运行 Testcontainers 或数据库迁移工具的环境