第二篇:Claude Code 在 Spring 项目中的实战工作流

上一篇讲完了原理,这篇直接说怎么用。

很多人拿到 Claude Code 之后,第一反应是"帮我重构一下 OrderService",然后发现效果不理想------要么改了不该改的地方,要么方案太粗糙根本没法落地。问题不在工具,在于驱动方式。这篇把一套经过验证的工作流梳理一遍,从准备工作到收尾验证,每个环节都说清楚。


一、重构前的准备工作

1.1 永远先做:让 Claude Code 生成项目地图

在让 Claude Code 动任何一行代码之前,先让它"读懂"项目。这一步非常关键,它决定了后续所有操作的质量。

指令:

markdown 复制代码
请分析 src/main/java 下的所有文件,生成一份项目架构报告,包括:
1. 各模块的类数量和代码行数统计
2. 模块间的依赖关系图(用文字描述)
3. 识别出违反分层架构的地方
4. 找出代码最复杂的前5个类(可以用行数或圈复杂度估算)

这个报告将成为你和 Claude Code 协作的"共同语言"。

1.2 建立安全基线:确保测试可运行

重构的黄金法则:没有测试就没有重构。在开始之前:

markdown 复制代码
请运行 mvn test 并告诉我:
1. 当前测试通过率是多少
2. 哪些模块没有单元测试
3. 如果测试覆盖率工具可用(JaCoCo),报告核心 Service 层的覆盖率

如果发现关键代码缺少测试,可以先让 Claude Code 补充测试:

css 复制代码
OrderService 中没有单元测试,在开始重构之前,
请为现有的 createOrder、cancelOrder、queryOrderById 
三个核心方法补充单元测试。使用 JUnit 5 + Mockito,
测试文件放在 src/test/java/com/example/order/service/

二、标准重构工作流:五步法

第一步:明确重构目标(Define)

不要用模糊的指令,要给出具体、可验证的目标:

❌ 模糊的指令(效果差):

复制代码
帮我把 OrderService 重构一下

✅ 具体的指令(效果好):

markdown 复制代码
OrderService.java 目前有 3120 行,需要按职责拆分。
以下是我的拆分设想,请评估可行性并提出改进建议:

1. OrderCreationService - 负责创建订单、校验库存、计算价格
2. OrderQueryService - 负责所有查询操作(只读,readOnly=true)
3. OrderStateService - 负责订单状态流转(已下单→已支付→已发货→已完成)
4. OrderRefundService - 负责退款和售后

原有的 OrderService 保留为门面类(Facade),将调用转发到上述4个类。
这样改动对外 API 不变,OrderController 无需修改。

请问这个方案有什么潜在问题?

第二步:制定变更计划(Plan)

在 Claude Code 动手之前,让它先输出详细计划:

diff 复制代码
基于上面的拆分方案,请列出完整的变更计划:
- 需要新建哪些文件(列出完整路径和类名)
- 需要修改哪些现有文件
- 方法迁移的映射表(哪个方法移到哪个新类)
- 可能的风险点
- 建议的执行顺序

暂时不要开始执行,等我确认计划后再动手。

示例输出计划:

scss 复制代码
变更计划如下:

【新建文件】
1. src/main/java/com/example/order/service/OrderCreationService.java
   迁入方法:createOrder(), validateInventory(), calculatePrice(),
            applyDiscount(), generateOrderNo()
   
2. src/main/java/com/example/order/service/OrderQueryService.java  
   迁入方法:findById(), listByUserId(), listByStatus(),
            countByDateRange(), exportOrders()

3. src/main/java/com/example/order/service/OrderStateService.java
   迁入方法:pay(), ship(), complete(), cancel(), 
            getStateTransitionHistory()

4. src/main/java/com/example/order/service/OrderRefundService.java
   迁入方法:applyRefund(), approveRefund(), rejectRefund(),
            processRefundPayment()

【修改文件】
5. src/main/java/com/example/order/service/OrderService.java
   改为门面类:注入上述4个 Service,方法实现改为委托调用
   
【可能的风险】
- OrderCreationService 和 OrderStateService 都需要发送消息队列通知,
  需要确认 RocketMQTemplate 的注入不会产生循环依赖
- OrderRefundService.processRefundPayment() 调用了 PaymentService,
  需要确认这是 OK 的跨模块依赖

【执行顺序建议】
第1步:创建4个新 Service 类(先只放方法签名,不迁移逻辑)
第2步:迁移 OrderQueryService(最安全,无副作用)
第3步:迁移 OrderCreationService
第4步:迁移 OrderStateService
第5步:迁移 OrderRefundService
第6步:修改 OrderService 为门面类
第7步:运行测试验证

是否确认执行?

第三步:逐步执行(Execute)

确认计划后,分步骤执行,不要让 Claude Code 一次性做所有改动:

复制代码
计划确认,请开始执行第1步和第2步:
创建4个新 Service 类的骨架(只有类定义、注解和方法签名,方法体先留空),
然后迁移 OrderQueryService 的方法实现。

完成后停下来,让我检查再继续。

这种"小步快跑"的方式让你随时掌握变更,遇到问题可以快速回滚。

第四步:验证变更(Verify)

每步完成后立即验证:

markdown 复制代码
OrderQueryService 迁移完成了,请执行以下验证:
1. 运行 mvn compile 确认编译通过
2. 运行 OrderQueryServiceTest(如果存在)
3. 在 OrderService 的门面方法中,将 queryOrderById 的实现改为调用 
   orderQueryService.findById(),然后重新编译

第五步:收尾清理(Cleanup)

重构完成后:

markdown 复制代码
重构完成,请做最后的收尾工作:
1. 删除 OrderService 中已经被迁移走的、不再需要的私有辅助方法
2. 确认所有新 Service 类都有正确的 Javadoc(至少类级别的注释)
3. 检查是否有 @SuppressWarnings 或临时的 TODO 注释需要处理
4. 运行完整的 mvn test,确认所有测试仍然通过
5. 生成一份变更摘要

三、处理复杂依赖:循环依赖是重构的大敌

Spring 项目重构中最常见的麻烦是循环依赖。比如重构后:

复制代码
OrderCreationService → InventoryService → OrderService → OrderCreationService

Claude Code 在处理这类问题时,你需要给它正确的引导:

markdown 复制代码
在迁移过程中,发现 OrderCreationService 和 InventoryService 存在循环依赖。
请分析并提供解决方案,可选方案包括:
1. 提取公共接口,通过接口解耦
2. 使用事件驱动(ApplicationEvent)解耦
3. 延迟注入(@Lazy)作为临时方案

请推荐最适合当前项目的方案,并说明理由。

Claude Code 的典型回答:

diff 复制代码
分析了调用关系后,循环依赖的根本原因是:
OrderCreationService.createOrder() 需要检查库存(调用 InventoryService),
而 InventoryService.reserveStock() 需要记录关联订单号(调用 OrderService 查询)。

这实际上是一个领域建模问题。推荐方案2------领域事件:

修改方案:
- 在 OrderCreationService.createOrder() 中,先创建订单(状态=待确认),
  然后发布 OrderCreatedEvent
- InventoryService 监听 OrderCreatedEvent,异步完成库存预留
- 取消 InventoryService 中对 OrderService 的直接调用

这种方式更符合 DDD 的设计原则,也让库存预留变为异步,
提升了下单接口的响应速度。

是否需要我展示完整的实现代码?

四、数据库迁移场景:修改 Entity 和 Repository

4.1 安全地重命名数据库字段

markdown 复制代码
需要将 order 表的 create_time 字段重命名为 created_at(统一命名规范)。
请帮我完成:
1. 修改 Order.java Entity 中的字段映射
2. 修改所有 OrderRepository 中引用了该字段的 JPQL/SQL
3. 检查是否有 XML mapper 文件(MyBatis)也需要修改
4. 生成对应的 Flyway 迁移脚本(V2__rename_create_time_to_created_at.sql)
5. 检查是否有前端 API 响应中直接暴露了这个字段名(需要同步修改 DTO)

4.2 拆分大表对应的 Entity

当一个 Entity 对应的表字段超过 50 个时,通常需要拆分:

sql 复制代码
Order 实体目前有 67 个字段,需要按业务域拆分:
- 核心字段(订单号、状态、金额等)保留在 Order 实体
- 收货地址相关字段(6个)提取到 OrderShippingAddress 值对象
- 发票相关字段(8个)提取到 OrderInvoice 值对象

请使用 JPA 的 @Embedded 方式实现,
并确保数据库表结构不变(所有字段仍在同一张 order 表)。

五、配置重构:统一管理散落的配置

企业级 Spring 项目通常有大量的配置散落在各处:

kotlin 复制代码
请帮我排查项目中所有的"配置坏味道":
1. 找出所有使用 @Value("${...}") 的地方,统计有多少个不同的配置项
2. 找出硬编码的字符串常量(URL、文件路径、业务参数等)
3. 检查 application.yml 是否有重复的配置项
4. 建议哪些配置应该迁移到统一的 @ConfigurationProperties 类中

重构后的目标是:每个模块有一个 XxxProperties.java 配置类:

java 复制代码
@ConfigurationProperties(prefix = "app.payment")
@Data
public class PaymentProperties {
    private String apiKey;
    private String callbackUrl;
    private Duration timeout = Duration.ofSeconds(30);
    private int maxRetry = 3;
}

六、团队协作场景:如何让 Claude Code 遵守团队规范

6.1 在 CLAUDE.md 中编码团队规范

markdown 复制代码
# CLAUDE.md

## 代码审查检查项(每次修改后必须自查)
- [ ] 新增的 public 方法必须有 Javadoc
- [ ] Service 方法必须有 @Transactional 注解
- [ ] 不允许在 catch 块中只写 e.printStackTrace(),必须用 log.error()
- [ ] 新增接口必须在 swagger 注解中写描述
- [ ] 数字字面量(除 0 和 1)必须定义为常量

## Git 提交规范
提交信息格式:<type>(<scope>): <description>
type: feat/fix/refactor/test/docs
示例:refactor(order): 将 OrderService 按职责拆分为4个子服务

6.2 让 Claude Code 生成符合规范的代码

在每次要求生成代码时,加上引用:

markdown 复制代码
请按照 CLAUDE.md 中定义的编码规范,
为 OrderStateService 中的 pay() 方法补充完整实现。
特别注意:
1. 事务注解不能省略
2. 状态流转失败时必须抛出 OrderStateException(不是 RuntimeException)
3. 每个状态变更都要发布领域事件

七、实战中的常见问题与解决

问题1:Claude Code 修改了不该修改的文件

解决: 在指令开头明确边界

css 复制代码
以下操作只能修改 order 模块(src/main/java/com/example/order/)下的文件,
不能修改 payment 模块和 common 模块的任何内容。

问题2:Claude Code 生成的代码不符合项目风格

解决: 给它一个参考示例

复制代码
请参考 ProductService.java 的代码风格(日志记录方式、异常处理模式、
注释格式),用相同的风格实现 OrderCreationService。

问题3:重构后编译通过但运行时出错

解决: 让它执行更完整的验证

markdown 复制代码
发现运行时报 NullPointerException,错误出现在 OrderService 第 45 行。
请:
1. 查看第 45 行的上下文
2. 检查 OrderCreationService 是否在所有需要注入它的地方都正确添加了 @Autowired
3. 检查 Spring 扫描配置(@ComponentScan)是否覆盖了新建的类所在的包

一句话原则

把上面这些方法压缩成一句话:小步快跑,每步验证,不要让 AI 一次性做太多。

这不是废话------实际使用中,很多人会把复杂的重构任务一股脑丢给 Claude Code,然后在输出里找 bug 找了半天。拆细、确认、执行、验证,这四个动作循环起来,才是真正省时间的方式。

相关推荐
牛奶3 小时前
AI辅助开发的基础概念
前端·人工智能·ai编程
牛奶11 小时前
2026年大模型怎么选?前端人实用对比
前端·人工智能·ai编程
牛奶12 小时前
前端人为什么要学AI?
前端·人工智能·ai编程
KEEN的创享空间18 小时前
AI编程从0到1之10X提效(Vibe Coding 氛围式编码 )09篇
openai·ai编程
AlienZHOU18 小时前
为 AI Agent 编写高质量 Skill:Claude 官方指南
agent·ai编程·claude
恋猫de小郭19 小时前
移动端开发稳了?AI 目前还无法取代客户端开发,小红书的论文告诉你数据
前端·flutter·ai编程
KaneLogger20 小时前
【翻译】打造 Agent Skills 的最佳实践
agent·ai编程·claude
王小酱20 小时前
Everything Claude Code 文档
openai·ai编程·aiops
雮尘21 小时前
如何在非 Claude IDE (TARE、 Cursor、Antigravity 等)下使用 Agent Skills
前端·agent·ai编程