AI 辅助 Java 开发实战:我用 Codex 写完了一个生产级项目

AI 辅助 Java 开发实战:我用 Codex 写完了一个生产级项目

不是 AI 替代程序员,而是会 AI 的程序员替代不会 AI 的程序员。

一、介绍

2024-2025 年,AI 编码工具彻底改变了我的开发方式。

从最初的好奇尝试,到现在的日常依赖------我的代码量中约 60% 由 AI 生成,但我花在思考和审查上的时间反而增加了 40%

这不是一篇工具教程。这是一篇实战复盘,记录我用 AI 辅助完成一个生产级 Java 项目的真实经验:踩过的坑、总结出的方法论、以及我认为每个 Java 开发者都应该知道的 AI 编码心法。


二、选对工具:我的 AI 编码工具箱

目前主流的 AI 编码工具有几个阵营:

工具 适合场景 我的评价
GitHub Copilot 日常补全、单元测试 补全准确率最高,但复杂逻辑生成不稳定
Codex CLI / Claude Code 复杂功能、重构、架构设计 理解上下文能力强,适合大块代码生成
Cursor / Windsurf 全流程开发 Agent 模式强,但 Java 项目支持略弱
Continue (VSCode 插件) 自定义模型接入 灵活,可接本地模型,适合隐私敏感场景

如果你主要写 Java,我的建议是:Copilot 做主补全 + Codex/Claude 做复杂功能生成,两者互补。


三、实战项目背景

一个真实的微服务模块:订单履约中心(Order Fulfillment Center)

  • 技术栈:Spring Boot 3.2 + MyBatis-Plus + RocketMQ + Redis
  • 核心功能:订单拆分、库存预占、物流路由、状态机流转
  • 代码量:约 1.5 万行

下面我用这个项目的真实片段,展示 AI 到底能帮到什么程度。


四、AI 编码的 5 个实战场景

场景 1:生成 POJO 和基础 CRUD ------ 最快最稳

这是 AI 最擅长的------重复、规律、模板化的工作。

我的提示词:

复制代码
生成一个订单明细表 OrderItem 的实体类,包含字段:
id, orderId, skuId, productName, quantity, price, totalAmount, createdAt, updatedAt
使用 Lombok,MyBatis-Plus 注解,继承 BaseEntity
同时生成 Mapper 接口和 Service 类

AI 输出(节选):

java 复制代码
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("order_item")
public class OrderItem extends BaseEntity {

    @TableId(type = IdType.AUTO)
    private Long id;

    private Long orderId;

    private Long skuId;

    private String productName;

    private Integer quantity;

    @TableField("price")
    private BigDecimal price;

    private BigDecimal totalAmount;

    private LocalDateTime createdAt;

    private LocalDateTime updatedAt;
}
java 复制代码
@Mapper
public interface OrderItemMapper extends BaseMapper<OrderItem> {
}
java 复制代码
@Service
@RequiredArgsConstructor
public class OrderItemService extends ServiceImpl<OrderItemMapper, OrderItem> {

    private final OrderItemMapper orderItemMapper;

    public List<OrderItem> getByOrderId(Long orderId) {
        return lambdaQuery().eq(OrderItem::getOrderId, orderId).list();
    }

    @Transactional
    public void batchSave(List<OrderItem> items) {
        saveBatch(items);
    }
}

实战体会: 这种代码 AI 生成基本不需要改,直接复制粘贴就行。单文件生成准确率 > 95%


场景 2:复杂业务逻辑 ------ AI 做框架,你做细节

这是最考验 prompt 能力的场景。看一个订单拆分逻辑:

我的提示词:

复制代码
实现订单拆分逻辑:
1. 订单可能包含多个商品(OrderItem)
2. 根据商品所属的仓库(warehouseId)进行拆分
3. 同一仓库的商品合并为一个子订单
4. 每个子订单需要计算商品总金额、总数量
5. 如果某个商品库存不足,抛出 BusinessException("商品xxx库存不足")
6. 拆分完成后,保存子订单并发送 RocketMQ 消息

用策略模式实现,考虑到未来可能有其他拆分规则

AI 生成了一个完整的 SplitStrategy 接口 + WarehouseSplitStrategy 实现类。我只需要调整仓库分配的细节逻辑。

java 复制代码
// AI 生成的核心策略
@Component
public class WarehouseSplitStrategy implements SplitStrategy {

    @Override
    public List<SubOrder> split(Order order, List<OrderItem> items) {
        // 按 warehouseId 分组
        Map<Long, List<OrderItem>> grouped = items.stream()
            .collect(Collectors.groupingBy(OrderItem::getWarehouseId));

        // 每组生成一个子订单
        return grouped.entrySet().stream()
            .map(entry -> createSubOrder(order, entry.getKey(), entry.getValue()))
            .collect(Collectors.toList());
    }

    private SubOrder createSubOrder(Order order, Long warehouseId, List<OrderItem> items) {
        SubOrder subOrder = new SubOrder();
        subOrder.setParentOrderId(order.getId());
        subOrder.setWarehouseId(warehouseId);
        subOrder.setStatus(SubOrderStatus.PENDING);

        BigDecimal totalAmount = items.stream()
            .map(OrderItem::getTotalAmount)
            .reduce(BigDecimal.ZERO, BigDecimal::add);

        subOrder.setTotalAmount(totalAmount);
        subOrder.setTotalQuantity(
            items.stream().mapToInt(OrderItem::getQuantity).sum()
        );
        subOrder.setItems(items);
        return subOrder;
    }
}

实战体会: 80% 的骨架代码 AI 能写对。但库存预占的锁逻辑事务边界异常处理的粒度------这些需要我亲手加。AI 不擅长你不知道它不知道的边界条件。


场景 3:单元测试 ------ AI 是真香

写单元测试是大部分开发者的痛点,AI 在这块是超强辅助。

我的提示词:

复制代码
为 OrderSplitService.split(order) 方法写单元测试:
1. 用 Mockito + JUnit 5
2. 覆盖正常拆分场景
3. 覆盖商品跨仓库拆分场景
4. 覆盖库存不足异常场景
5. 覆盖订单为空异常场景
6. 验证 RocketMQ 消息是否正确发送

AI 生成的测试代码直接可运行度很高:

java 复制代码
@ExtendWith(MockitoExtension.class)
class OrderSplitServiceTest {

    @Mock
    private OrderItemService orderItemService;

    @Mock
    private RocketMQProducer rocketMQProducer;

    @InjectMocks
    private OrderSplitService orderSplitService;

    @Test
    void shouldSplitOrderByWarehouse() {
        // given
        Order order = new Order();
        order.setId(1L);

        List<OrderItem> items = Arrays.asList(
            createItem(1L, "SKU-A", 1001L, new BigDecimal("99.00"), 2),
            createItem(2L, "SKU-B", 1002L, new BigDecimal("199.00"), 1),
            createItem(3L, "SKU-C", 1001L, new BigDecimal("59.00"), 1)
        );

        // when
        List<SubOrder> subOrders = orderSplitService.split(order, items);

        // then
        assertThat(subOrders).hasSize(2);

        SubOrder warehouse1001 = subOrders.stream()
            .filter(s -> s.getWarehouseId().equals(1001L))
            .findFirst().orElseThrow();
        assertThat(warehouse1001.getItems()).hasSize(2); // SKU-A + SKU-C
        assertThat(warehouse1001.getTotalAmount())
            .isEqualByComparingTo(new BigDecimal("257.00"));

        SubOrder warehouse1002 = subOrders.stream()
            .filter(s -> s.getWarehouseId().equals(1002L))
            .findFirst().orElseThrow();
        assertThat(warehouse1002.getItems()).hasSize(1); // SKU-B

        verify(rocketMQProducer).send(any(Message.class));
    }
}

实战体会: 测试覆盖率从 45% 飙升到 92%。AI 生成的测试覆盖面广 ,各种边界情况都考虑到了。我只需要检查断言是否符合预期逻辑。写测试的时间从 40% 降到 10%


场景 4:代码审查 ------ AI 是第二双眼睛

把代码贴给 AI 做 Code Review:

java 复制代码
// 这是我写的原始代码
public Order createOrder(CreateOrderRequest request) {
    Order order = new Order();
    order.setUserId(request.getUserId());
    order.setTotalAmount(request.getItems().stream()
        .map(i -> i.getPrice().multiply(BigDecimal.valueOf(i.getQuantity())))
        .reduce(BigDecimal.ZERO, BigDecimal::add));
    orderMapper.insert(order);
    for (OrderItem item : request.getItems()) {
        item.setOrderId(order.getId());
        orderItemMapper.insert(item);
    }
    return order;
}

AI Review 结果:

  1. ⚠️ 事务问题orderMapper.insert + orderItemMapper.insert 没有事务保护,中间失败会导致数据不一致
  2. ⚠️ 金额精度BigDecimal 乘法要用 setScale(2, RoundingMode.HALF_UP) 确保精度
  3. ⚠️ 批量插入性能 :逐条 insert 在大数据量下慢,建议用 insertBatch
  4. ⚠️ 空指针风险request.getItems() 可能为 null

修正后的代码:

java 复制代码
@Transactional(rollbackFor = Exception.class)
public Order createOrder(CreateOrderRequest request) {
    if (CollectionUtils.isEmpty(request.getItems())) {
        throw new BusinessException("订单商品不能为空");
    }

    Order order = new Order();
    order.setUserId(request.getUserId());
    order.setTotalAmount(request.getItems().stream()
        .map(i -> i.getPrice().multiply(BigDecimal.valueOf(i.getQuantity()))
            .setScale(2, RoundingMode.HALF_UP))
        .reduce(BigDecimal.ZERO, BigDecimal::add)
        .setScale(2, RoundingMode.HALF_UP));
    orderMapper.insert(order);

    List<OrderItem> orderItems = request.getItems().stream()
        .map(item -> {
            OrderItem orderItem = new OrderItem();
            BeanUtils.copyProperties(item, orderItem);
            orderItem.setOrderId(order.getId());
            return orderItem;
        })
        .collect(Collectors.toList());
    orderItemService.saveBatch(orderItems);

    return order;
}

实战体会: AI Review 发现了我忽略的 4 个问题。我现在任何代码合并前都会让 AI 过一遍,比自己两眼一抹黑看三遍管用。


场景 5:重构老代码 ------ AI 是真正的救星

一个 300 行的 OrderService 方法,if-else 嵌套 5 层。

我的提示词:

复制代码
这个方法太长了,帮我重构:
1. 提取每个分支为独立方法
2. 用策略模式替代 if-else
3. 状态流转用枚举 + 状态机
4. 保持原有业务逻辑不变
5. 每个新方法都要有 JavaDoc

AI 把 300 行拆成了:

  • OrderStateMachine --- 状态机引擎
  • OrderStateHandler 接口 + 5 个实现类
  • OrderEventPublisher --- 事件发布

代码量从 300 行变成了 600 行,但可维护性翻了几倍 。后来需求变更,加一个新状态只需要加一个 Handler 类,零改动旧代码


五、我的 AI 编码心法(建议收藏)

心法 1:写好 Prompt 比写好代码更重要

markdown 复制代码
❌ 差的 prompt:写一个订单服务
✅ 好的 prompt:
  写一个 OrderService,需要:
  1. 创建订单(校验库存→扣库存→保存订单→发消息)
  2. 取消订单(校验状态→回滚库存→更新状态→发消息)
  3. 使用 @Transactional 管理事务
  4. 异常使用 BusinessException
  5. 用 MyBatis-Plus 操作数据库

原则:给 AI 足够的信息,但不要让它猜。

心法 2:分步生成,不要一次搞定

不要这样:写一个完整的订单履约系统

要这样:

  1. 生成 Order 实体类
  2. 生成 OrderMapper
  3. 生成创建订单的业务逻辑
  4. 生成单元测试

AI 在单步任务上准确率高,多步长任务容易跑偏。

心法 3:AI 生成,人工审查,缺一不可

这是我给自己定的铁律:

复制代码
AI 写 → 我审 → 我改 → AI Review → 合入

每个环节不可跳过。AI 生成的代码至少有一个隐晦的 bug,这是我几十次实战验证的结论。可能是竞态条件、事务边界、或者是 JDK 版本的 API 差异。

心法 4:让 AI 做擅长的事

AI 擅长 AI 不擅长
生成样板代码 架构决策
写单元测试 领域建模
代码审查找漏 性能瓶颈定位
重构提取方法 全局一致性保证
解释遗留代码 安全漏洞防护
生成文档注释 业务规则挖掘

六、真实收益数据

这个项目做完后我统计了一下:

指标 使用 AI 前 使用 AI 后 提升
单功能开发周期 2.5 天 1 天 60% ↓
测试覆盖率 45% 92% 104% ↑
线上 Bug 率 平均 3 个/版本 0 个 追零
代码重复率 18% 6% 67% ↓

最意外的是 Bug 率下降 ------不是因为 AI 写的代码没 bug,而是因为我多出来的时间全用来做 Code Review 和测试了


七、总结

AI 不会取代你,但会用 AI 的开发者会取代你。

我自己也走过弯路------一开始觉得 AI 写的代码不放心,每行都自己改;后来发现太浪费时间,开始信任 AI 处理模板化工作;现在找到了平衡点:AI 做执行,我做决策

这不是偷懒,而是把精力花在真正有价值的事上------理解业务、设计架构、保障质量。

最后送各位三句话:

  1. 不要抗拒 AI --- 学起来,把它变成你的"超级实习生"
  2. 不要盲信 AI --- 它写的代码,你要负全责
  3. 不要停止思考 --- AI 能做 80% 的工作,但那 20% 的决策和判断,才是你的价值

互动话题:你平时用 AI 写代码吗?有没有什么神 prompt 或者踩坑经历?评论区见!