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

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 输出(节选):

@Data@EqualsAndHashCode(callSuper=true)@TableName("order_item")publicclassOrderItemextendsBaseEntity{@TableId(type=IdType.AUTO)privateLongid;privateLongorderId;privateLongskuId;privateStringproductName;privateIntegerquantity;@TableField("price")privateBigDecimalprice;privateBigDecimaltotalAmount;privateLocalDateTimecreatedAt;privateLocalDateTimeupdatedAt;}
@MapperpublicinterfaceOrderItemMapperextendsBaseMapper<OrderItem>{}
@Service@RequiredArgsConstructorpublicclassOrderItemServiceextendsServiceImpl<OrderItemMapper,OrderItem>{privatefinalOrderItemMapperorderItemMapper;publicList<OrderItem>getByOrderId(LongorderId){returnlambdaQuery().eq(OrderItem::getOrderId,orderId).list();}@TransactionalpublicvoidbatchSave(List<OrderItem>items){saveBatch(items);}}

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


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

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

我的提示词:

实现订单拆分逻辑: 1. 订单可能包含多个商品(OrderItem) 2. 根据商品所属的仓库(warehouseId)进行拆分 3. 同一仓库的商品合并为一个子订单 4. 每个子订单需要计算商品总金额、总数量 5. 如果某个商品库存不足,抛出 BusinessException("商品xxx库存不足") 6. 拆分完成后,保存子订单并发送 RocketMQ 消息 用策略模式实现,考虑到未来可能有其他拆分规则

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

// AI 生成的核心策略@ComponentpublicclassWarehouseSplitStrategyimplementsSplitStrategy{@OverridepublicList<SubOrder>split(Orderorder,List<OrderItem>items){// 按 warehouseId 分组Map<Long,List<OrderItem>>grouped=items.stream().collect(Collectors.groupingBy(OrderItem::getWarehouseId));// 每组生成一个子订单returngrouped.entrySet().stream().map(entry->createSubOrder(order,entry.getKey(),entry.getValue())).collect(Collectors.toList());}privateSubOrdercreateSubOrder(Orderorder,LongwarehouseId,List<OrderItem>items){SubOrdersubOrder=newSubOrder();subOrder.setParentOrderId(order.getId());subOrder.setWarehouseId(warehouseId);subOrder.setStatus(SubOrderStatus.PENDING);BigDecimaltotalAmount=items.stream().map(OrderItem::getTotalAmount).reduce(BigDecimal.ZERO,BigDecimal::add);subOrder.setTotalAmount(totalAmount);subOrder.setTotalQuantity(items.stream().mapToInt(OrderItem::getQuantity).sum());subOrder.setItems(items);returnsubOrder;}}

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


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

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

我的提示词:

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

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

@ExtendWith(MockitoExtension.class)classOrderSplitServiceTest{@MockprivateOrderItemServiceorderItemService;@MockprivateRocketMQProducerrocketMQProducer;@InjectMocksprivateOrderSplitServiceorderSplitService;@TestvoidshouldSplitOrderByWarehouse(){// givenOrderorder=newOrder();order.setId(1L);List<OrderItem>items=Arrays.asList(createItem(1L,"SKU-A",1001L,newBigDecimal("99.00"),2),createItem(2L,"SKU-B",1002L,newBigDecimal("199.00"),1),createItem(3L,"SKU-C",1001L,newBigDecimal("59.00"),1));// whenList<SubOrder>subOrders=orderSplitService.split(order,items);// thenassertThat(subOrders).hasSize(2);SubOrderwarehouse1001=subOrders.stream().filter(s->s.getWarehouseId().equals(1001L)).findFirst().orElseThrow();assertThat(warehouse1001.getItems()).hasSize(2);// SKU-A + SKU-CassertThat(warehouse1001.getTotalAmount()).isEqualByComparingTo(newBigDecimal("257.00"));SubOrderwarehouse1002=subOrders.stream().filter(s->s.getWarehouseId().equals(1002L)).findFirst().orElseThrow();assertThat(warehouse1002.getItems()).hasSize(1);// SKU-Bverify(rocketMQProducer).send(any(Message.class));}}

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


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

把代码贴给 AI 做 Code Review:

// 这是我写的原始代码publicOrdercreateOrder(CreateOrderRequestrequest){Orderorder=newOrder();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(OrderItemitem:request.getItems()){item.setOrderId(order.getId());orderItemMapper.insert(item);}returnorder;}

AI Review 结果:

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

修正后的代码:

@Transactional(rollbackFor=Exception.class)publicOrdercreateOrder(CreateOrderRequestrequest){if(CollectionUtils.isEmpty(request.getItems())){thrownewBusinessException("订单商品不能为空");}Orderorder=newOrder();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->{OrderItemorderItem=newOrderItem();BeanUtils.copyProperties(item,orderItem);orderItem.setOrderId(order.getId());returnorderItem;}).collect(Collectors.toList());orderItemService.saveBatch(orderItems);returnorder;}

实战体会: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 比写好代码更重要

❌ 差的 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 或者踩坑经历?评论区见!