完整实战:为 Java + Spring Boot 团队搭建 Claude Code 规范
前几篇分别讨论了职责分离、路径规则、Hooks、CI 和规则演进。这一篇把这些内容组合起来,为一个 Java + Spring Boot 订单服务建立完整的基础配置。
示例不是通用标准答案。团队应该根据自己的异常模型、日志组件、数据库访问方式和测试体系调整。
项目结构
假设项目采用 Java 17、Spring Boot 3、PostgreSQL、Redis、Maven 和 Flyway:
order-service/
├── CLAUDE.md
├── pom.xml
├── src/
│ ├── main/
│ └── test/
└── .claude/
├── settings.json
├── rules/
│ ├── coding-style.md
│ ├── api-design.md
│ ├── database.md
│ ├── testing.md
│ └── controller.md
└── skills/
└── db-migration/
└── SKILL.md
其中:
CLAUDE.md保存项目常驻事实。coding-style.md、api-design.md保存全局规范。database.md、controller.md使用路径限定范围。testing.md定义测试策略。db-migrationSkill 保存迁移操作流程。.claude/settings.json共享团队级 Hook 或权限配置,具体内容需按组织安全要求编写。
CLAUDE.md:只保留高频项目上下文
# 订单服务
## 技术栈
- Java 17
- Spring Boot 3.x
- PostgreSQL
- Redis
- Maven
- Flyway
## 常用命令
- 启动服务:`mvn spring-boot:run`
- 运行单元测试:`mvn test`
- 完整验证:`mvn verify`
- 代码风格检查:`mvn checkstyle:check`
## 目录职责
- `src/main/java/com/example/order/controller`:HTTP 协议适配与参数校验
- `src/main/java/com/example/order/service`:业务流程与事务边界
- `src/main/java/com/example/order/repository`:数据访问
- `src/main/java/com/example/order/domain`:领域模型
- `src/main/resources/db/migration`:Flyway migration
- `src/test`:测试代码
## 架构边界
- Controller 不实现业务逻辑,不直接访问 Repository
- Service 负责业务流程和事务边界
- Repository 不返回 HTTP 层模型
- 外部系统调用通过明确的 Client/Adapter 封装
## 项目红线
- 数据库结构变更必须提供 Flyway migration
- 不提交 `application-local.yml`、真实凭据和生产数据
- 支付、价格计算、权限和退款相关修改必须请求人工评审
- 完成修改后运行与改动范围相匹配的测试,并说明结果
这里没有复制所有数据库、API 和测试细节,因为这些内容分别由 rules 负责。
coding-style.md:全局代码风格
# Java 代码风格
## 命名
- 类、接口和枚举使用 PascalCase
- 方法和变量使用 camelCase
- 常量使用 UPPER_SNAKE_CASE
- 布尔值使用能够表达判断含义的前缀,如 is、has、can
## 日志
- 使用 SLF4J,不使用 System.out、System.err 或 printStackTrace
- 日志使用参数化占位符,不做字符串拼接
- 关键错误包含 traceId 和业务实体 ID
- 禁止记录密码、Token、Cookie、银行卡号和完整个人敏感信息
不要这样:
```java
System.out.println("Order failed: " + orderId);
应该这样:
log.error("Order processing failed, orderId={}", orderId, exception);
异常处理
- 仅在能够恢复、转换异常或增加关键上下文的边界捕获异常
- 不吞异常,不只打印堆栈
- 业务异常使用项目现有异常类型
- HTTP 错误转换由全局异常处理器负责
- 避免在多个调用层重复记录同一个异常
修改原则
- 优先复用现有组件和模式
- 不在无关功能修改中进行大范围重构
- 公开行为改变时同步更新测试和必要文档
与“所有对外方法都必须 try-catch”相比,这里的规则更准确。并不是捕获得越多越安全;没有恢复、转换或补充上下文价值的捕获,往往只会造成重复日志和样板代码。
## api-design.md:API 规范
```markdown
# API 设计规范
## 路径与方法
- API 路径使用小写复数资源名,如 `/orders`、`/users`
- 使用 HTTP 方法表达操作语义
- 查询条件使用 query 参数
- 不在路径中使用动词表达普通 CRUD 操作
## 输入校验
- 所有外部输入在进入 Service 前完成校验
- 必填字符串拒绝 null、空字符串和纯空白
- 数值参数定义业务范围
- 枚举参数拒绝未知值
- 分页参数使用 `page` 和 `pageSize`,`pageSize` 最大为 100
- DTO 优先使用 Bean Validation 和项目现有自定义校验器
## 响应与错误
- 响应格式沿用项目现有 Result 模型
- 列表接口返回 items、page、pageSize 和 total
- 业务错误映射为公开错误码
- 不向客户端暴露堆栈、SQL、内部类名和数据库结构
- HTTP 状态码与错误语义保持一致
## 兼容性
- 修改公开请求或响应字段前检查向后兼容性
- 删除或重命名字段需要明确迁移计划
- 新增端点或改变契约时同步更新 OpenAPI 描述
“统一响应格式”必须以项目当前实现为准。如果公司网关已经完成包装,应用层就不应再次包装。
database.md:数据库规则
数据库规则可以只在 Repository、Mapper 和 migration 文件附近加载:
---
paths:
- "src/main/java/**/repository/**/*.java"
- "src/main/java/**/mapper/**/*.java"
- "src/main/resources/db/migration/**/*.sql"
---
# 数据库规范
## 查询
- 明确选择所需字段,避免无目的使用 SELECT *
- 分页接口单次最多返回 100 条
- 新增复杂查询时确认索引和执行计划
- 避免循环中逐条查询造成 N+1
## 写入
- 批量写入使用项目支持的 batch 方案
- 多表原子写入在 Service 层定义事务边界
- 更新和删除必须包含明确条件
- 逻辑删除或物理删除遵循对应表的数据保留策略,不自行决定
## migration
- 所有结构变更通过新的 Flyway migration 完成
- 已在共享环境执行的 migration 不得直接修改
- migration 包含可验证的前向变更和必要说明
- 大表变更需要评估锁表、回填和回滚风险
## 事务
- 事务边界放在业务 Service,而不是 Controller
- 事务中避免非必要的远程调用、消息等待和长时间计算
- 注意 Spring 代理模式下同类内部调用可能绕过事务代理
- 涉及消息与数据库一致性时沿用项目现有 outbox 或补偿方案
这里没有把“所有数据都逻辑删除”写成全局真理。删除策略应该结合隐私要求、数据保留周期、索引和业务审计需求决定。
关于 @Transactional,在 Spring 常见的代理模式中,通过 this 的内部调用会绕过代理,因此目标方法上的事务拦截可能不会执行。更好的做法通常是重新划分 Service 边界,避免依赖同类自调用触发事务。
controller.md:Controller 路径规则
---
paths:
- "src/main/java/**/controller/**/*.java"
---
# Controller 层规范
- Controller 只负责协议适配、权限入口、参数校验和调用 Service
- 请求 DTO 使用 `@Valid` 或 `@Validated`
- 不在 Controller 编写业务计算
- 不直接访问 Repository、Mapper 或 EntityManager
- 返回项目统一响应模型
- 错误交给全局异常处理器,不在每个方法复制 try-catch
- 修改状态码、请求校验或响应结构时增加 Controller 集成测试
该规则只影响 Controller,放成路径规则可以避免处理 Service 和 Repository 时占用上下文。
testing.md:测试规范
# 测试规范
## 基本要求
- 修复缺陷时先增加能够复现问题的回归测试
- 修改分支逻辑时覆盖成功、失败和关键边界条件
- 测试应验证外部可见行为,避免过度依赖内部实现细节
- 不通过降低断言、删除测试或扩大忽略范围来让测试通过
## 测试类型
- Service 业务分支优先使用单元测试
- Controller 校验、状态码和响应模型使用 Web 层集成测试
- Repository 查询和映射使用数据库集成测试
- 涉及完整关键流程时使用端到端测试
## 命名与目录
- 测试放在与生产包结构对应的 `src/test/java` 目录
- 测试类以 `Test` 或项目现有约定结尾
- 用例名称表达行为和条件
## 验证
- 修改局部逻辑时先运行相关测试
- 提交前运行 `mvn verify`
- 无法运行某项测试时明确说明原因,不得声称已经通过
db-migration Skill:把流程从规则中分离
迁移不仅有编码约定,还有完整操作流程,因此适合做成 Skill。其内容可以包括:
- 检查当前 Flyway 版本和命名规则。
- 创建新的 migration,不修改已执行文件。
- 评估锁表、索引和数据回填风险。
- 在本地空库验证从零迁移。
- 在已有数据快照上验证增量迁移。
- 运行 Repository 集成测试。
- 输出发布、观察和回滚说明。
这样只有真正进行数据库迁移时才加载完整流程。
自动化验证建议
上述自然语言规则仍然只是指导,团队还应在 CI 中落实:
mvn checkstyle:checkmvn test或mvn verify- SpotBugs、PMD 或团队选定的静态分析
- ArchUnit 分层依赖检查
- Flyway migration 验证
- Secret Scan
- 依赖漏洞扫描
对于支付、权限、价格和退款代码,可使用 CODEOWNERS 或保护规则要求指定负责人评审。
验证规则是否生效
配置完成后:
- 使用
/context检查加载的说明文件。 - 让 Claude 修改一个 Controller,观察
controller.md是否进入上下文。 - 修改 Repository 文件,检查数据库规则是否按需加载。
- 运行 lint 和测试确认生成结果。
- 通过一次真实小功能试点,而不是只生成孤立示例代码。
小结
完整配置并不意味着把所有要求都写进一个文件,而是清楚分层:
CLAUDE.md负责项目事实和常驻边界。- 全局 rules 负责跨模块规范。
- 路径 rules 负责 Controller、数据库等局部要求。
- Skills 负责数据库迁移等长流程。
- CI 和评审负责最终门禁。
下一篇也是本系列最后一篇,将讨论个人项目和团队项目的不同组合,以及落地时最容易踩到的坑。