用 Claude Code 写 Java 代码有一段时间了,从一开始的磕磕绊绊到现在能稳定产出符合团队规范的代码,踩了不少坑。这篇分享一下我的优化思路。

问题在哪

实际用下来,Claude Code 在 Java 项目上经常出这些问题:

  • 反复确认:每次生成代码都要问”你们项目是用构造器注入还是字段注入?””BaseTest 放在哪?”
  • 风格漂移:同一份代码,这次生成的 Controller 用 Mono<Result<T>>,下次就变成 ResponseEntity<T>
  • 测试混乱:MockMvc、WebTestClient、@DataJpaTest 混着来,不确定该用哪个
  • 规范散落在各处:Java 规范在项目 A,测试规范在项目 B,每次都要翻好几个文件

根本原因是:Claude 没有一个统一的地方快速获取项目规范

解决思路

把分散的规范整合到一个 Claude Code 能第一时间读取的地方:

  1. 全局规范~/.claude/CLAUDE.md(放跨项目的通用规范)
  2. 项目模板.claude/templates.md(放项目特定的代码模板)
  3. 示例代码 → 用可运行的示例验证规范是否被正确应用

具体怎么做

1. 建立全局规范文件

在用户目录下创建 ~/.claude/CLAUDE.md,内容按优先级排列:

基础编码习惯

1
2
3
4
5
6
7
8
9
10
// 日志只用 SLF4J
@Slf4j
public class UserService {
public void createUser(UserRequest request) {
log.info("创建用户: {}", request.getName());
}
}

// 禁止这个
System.out.println("调试信息");

依赖注入方式

1
2
3
4
5
6
7
8
9
10
11
12
13
// 用这个
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
}

// 不要用这个
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
}

Controller 模板(Spring Boot 3.x + WebFlux)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Controller
@RequestMapping("/api/v1/resource")
@RequiredArgsConstructor
public class ResourceController {
private final ResourceService resourceService;

@PostMapping
public Mono<Result<ResourceResponse>> create(@RequestBody ResourceRequest request) {
return resourceService.create(request);
}

@PostMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ResourceEvent> stream(@RequestBody ResourceRequest request) {
return resourceService.stream(request);
}
}

测试写法

1
2
3
4
5
6
7
8
9
10
11
12
13
// 所有测试继承 BaseTest
@ActiveProfiles("dev")
@SpringBootTest(classes = {TestApplication.class})
public abstract class BaseTest {}

// 测试方法命名:should_预期结果_When_条件
@Test
@DisplayName("创建资源 - 成功场景")
void should_CreateResource_When_RequestIsValid() {
// Given - 准备数据
// When - 执行操作
// Then - 验证结果
}

2. 项目级模板

在项目根目录建 .claude/templates.md,放一些重复率高的代码结构:

  • Controller 骨架(含异常处理)
  • Service 层标准结构
  • Repository 方法命名约定
  • Entity + DTO 转换模板

这样 Claude 生成代码时直接套用,不用每次都从零推理。

3. 验证规范生效

建一个 ExampleController 测试一下,看看 Claude 是否自动应用了规范:

  • 有没有用 @RequiredArgsConstructor
  • 返回类型是不是 Mono<Result<T>>
  • 日志是不是 log.info 而不是 System.out
  • 测试有没有继承 BaseTest

如果不对,回头调整 CLAUDE.md 的表述方式,直到稳定输出符合预期的代码。

效果如何

拿”创建一个完整的 Controller + Service + Test”这个场景对比:

环节 优化前 优化后
确认项目规范 30-60 秒翻文件 0 秒,直接套用
生成代码 2 分钟 1 分钟
修复编译错误 3 分钟(风格不一致导致) 基本为 0
总计 ~7 分钟 ~1 分钟

更关键的是代码风格统一了,Review 的时候不用再说”这里应该用构造器注入”。

完整的 CLAUDE.md 结构

我的全局规范文件长这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Java 编程规范

## 通用规范
- 日志:SLF4J + Lombok @Slf4j
- 注入:构造器注入 + @RequiredArgsConstructor
- 命名:类名大驼峰,方法名小驼峰,常量全大写下划线

## Spring Boot 3.x + WebFlux
- Controller 返回统一用 Mono<Result<T>>
- 流式接口用 Flux<T> + TEXT_EVENT_STREAM_VALUE
- 异常统一在 GlobalExceptionHandler 处理

## 测试规范
- 必须继承 BaseTest
- 方法命名:should_XXX_When_YYY
- 一个测试只验证一个概念

## 项目特定(wormhole-agent)
- BaseTest 路径:...wormhole.test.BaseTest
- 统一响应类:Result<T>
- 包结构:controller/service/repository/entity/dto

## 禁止清单
- 字段注入(@Autowired 在字段上)
- System.out.println
- 方法超过 50 行
- 捕获异常不记录堆栈

额外收益

技能调用指南:在规范里注明什么场景调用什么 Skill,比如:

  • 遇到 Java 报错 → 自动调用 c-java-master
  • 需要重构代码 → /重构 触发 c-spring-refactor
  • 写测试用例 → /测试 触发 c-java-tester

质量检查清单:生成代码前 Claude 会自动确认:

  • 构造器注入?
  • 方法行数 < 30?
  • 异常记录完整堆栈?

快速开始

如果你想复用这套方案:

  1. 复制上面的规范结构到 ~/.claude/CLAUDE.md
  2. 改成你项目的包名、响应类名、测试基类路径
  3. 创建一个测试 Controller,验证 Claude 的输出
  4. 根据结果微调规范文件的表述

不需要一次做到完美,先用起来,再慢慢迭代。

参考


这套方法的核心就三点:规范集中管理、代码模板化、用示例验证。不是什么高深的技术,但确实能让 AI 辅助编码的体验上一个台阶。

有问题欢迎在评论区交流。