欢迎光临
我们一直在努力

Spring Boot 3.3 + AI Agent 实战:从API调用到智能代码生成,手把手带你落地

文章目录

写在前面 上一篇文章讲了我用AI写代码踩的7个坑,很多人看完问我:那你现在到底怎么让AI Agent帮你干活的?能不能出个能直接抄的教程?

今天这篇就是。我会从头搭一个Spring Boot项目,接上AI Agent的能力,让它自动生成CRUD代码、自动写单元测试、自动做代码审查。每一步都有完整代码,照着跑就能复现。

环境说明:Spring Boot 3.3.0、JDK 21、Maven 3.9、macOS 14。AI Agent部分基于通用的API调用方式,不绑定特定产品。

注意:所有代码经过实际运行验证,但你的项目环境和业务规则不同,直接复制需做适配。

一、为什么要把AI Agent接进Spring Boot 先解决一个根本问题:你让AI帮你写代码,为什么还要手动复制粘贴?

大多数开发者现在的AI编程方式是这样的。在IDE里写代码,切到浏览器或另一个窗口问AI。“帮我写一个用户查询接口,支持分页和模糊搜索”。AI返回代码,你复制回来,粘贴到IDEA里,改import、改包名、改数据库字段,跑一下发现三个地方报错——改完才算搞定。

这个过程里最浪费时间的不是想逻辑,是复制粘贴和调试。

AI Agent能干什么呢。你告诉它需求,它自己读取项目结构、自己写代码到对应文件、自己导入依赖、自己跑测试、报错了自己修。你把"翻译需求为代码"和"复制粘贴调试"这两步都省了,只留下"定义需求"和"审查结果"。

下面就开始搭。

二、搭建项目脚手架 先建一个标准的Spring Boot项目。

打开IDEA,New Project → Spring Initializr。选JDK 21,依赖勾选Spring Web、Spring Data JPA、MySQL Driver、Lombok、Spring Boot DevTools。项目名随便取,我这里叫ai-agent-demo。

建好后的项目结构:

src/main/java/com/example/aiagentdemo/ ├── AiAgentDemoApplication.java ├── controller/ ├── service/ ├── repository/ └── entity/

pom.xml的关键依赖确认一下版本:

Spring Boot 3.3.0,Spring Data JPA通过spring-boot-starter-data-jpa引入,MySQL连接器版本8.0.33,Lombok用最新版(1.18.30)。

application.yml配置数据库连接:

spring: datasource: url: jdbc:mysql://localhost:3306/ai_demo?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai username: root password: your_password driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: ddl-auto: update show-sql: true properties: hibernate: format_sql: true

确认项目能正常启动。运行AiAgentDemoApplication,看控制台有没有Spring的banner和端口启动信息(默认8080)。如果启动失败,先检查数据库是否创建、账号密码是否正确。

三、设计AI Agent的交互接口 这一节是关键。我们不绑定任何特定AI产品,只定义一套通用的交互方式。

先确定AI Agent需要什么信息才能帮你干活。第一,项目结构(有哪些模块、有哪些类)。第二,现有代码内容(不然它怎么知道在哪个文件里加方法)。第三,你的需求描述(要生成什么功能)。

定义一个AgentRequest类来承载这些信息:

public class AgentRequest { private String requirement; // 需求描述 private String targetFile; // 目标文件路径 private String contextCode; // 上下文代码(可选) private List dependencies; // 需要的依赖 }

AI返回的结果也很明确。生成的代码内容、写入的代码位置、是否需要新增依赖。

定义一个AgentResponse:

public class AgentResponse { private String generatedCode; // 生成的代码 private String filePath; // 写入路径 private List newDependencies; // 需要新增的依赖 private String explanation; // AI对代码的解释 }

有了这两个数据结构,接下来需要实现三个核心能力。第一,把AgentRequest发送给AI服务并拿到AgentResponse。第二,把生成的代码写入指定文件。第三,如果生成了新依赖,自动更新pom.xml。

先写AI服务的调用层:

@Service public class AgentService {

public AgentResponse generateCode(AgentRequest request) { // 1. 组装prompt String prompt = buildPrompt(request);

// 2. 调用AI API(这里用通用的HTTP方式,你可以替换成任何AI服务的API)
String rawResponse = callAiApi(prompt);

// 3. 解析返回结果为AgentResponse
return parseResponse(rawResponse);

}

private String buildPrompt(AgentRequest request) { return String.format(“”" 你是一个Spring Boot开发助手。请根据以下信息生成代码:

需求:%s
目标文件:%s
上下文代码:%s
已有依赖:%s

要求:
1. 生成完整的、可直接运行的Java代码
2. 遵循项目现有的包结构和命名规范
3. 包含必要的import语句
4. 如果涉及数据库操作,使用Spring Data JPA
5. 如果涉及接口,使用RestController
6. 如果需要新的Maven依赖,列出来

只返回代码,不要解释。
""",
request.getRequirement(),
request.getTargetFile(),
request.getContextCode() != null ? request.getContextCode() : "无",
request.getDependencies() != null ? String.join(", ", request.getDependencies()) : "无"
);

} }

callAiApi方法的具体实现取决于你用的AI服务。如果是OpenAI格式的API:

private String callAiApi(String prompt) { // 伪代码,具体实现看你用的AI服务 // POST https://your-ai-api-endpoint/v1/chat/completions // Body: { “model”: “your-model”, “messages”: [{“role”: “user”, “content”: prompt}] } // 返回response.choices[0].message.content return aiClient.chat(prompt); }

然后是代码写入服务,负责把AI生成的代码写进项目:

@Service public class CodeWriterService {

private static final String PROJECT_ROOT = “src/main/java/com/example/aiagentdemo/”;

public void writeCode(AgentResponse response) throws IOException { Path filePath = Paths.get(PROJECT_ROOT + response.getFilePath());

// 确保父目录存在
Files.createDirectories(filePath.getParent());

// 写入代码
Files.writeString(filePath, response.getGeneratedCode());

System.out.println("代码已写入:" + filePath.toAbsolutePath());

}

public void addDependencies(List dependencies) throws IOException { if (dependencies == null || dependencies.isEmpty()) { return; }

Path pomPath = Paths.get("pom.xml");
String pomContent = Files.readString(pomPath);

for (String dependency : dependencies) {
// 检查是否已存在
if (!pomContent.contains(dependency)) {
// TODO: 使用Maven模型解析和修改pom.xml
// 简化起见,这里只打印提示
System.out.println("需要手动添加依赖:" + dependency);
}
}

} }

四、实战:让AI Agent生成一个完整的CRUD模块 好了,基础设施搭完了。现在来跑一个真实场景。

场景:电商系统里需要一个商品管理模块,包含创建商品、查询商品列表(支持模糊搜索和分页)、更新商品信息、删除商品。数据库已经有了product表,字段包括id、name、description、price、stock、category、create_time、update_time。

第一步,定义实体类。

AI需要先知道数据库表结构。在entity包下建Product.java:

@Entity @Table(name = “product”) @Data @NoArgsConstructor @AllArgsConstructor public class Product { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;

@Column(nullable = false, length = 200) private String name;

@Column(columnDefinition = “TEXT”) private String description;

@Column(nullable = false) private BigDecimal price;

@Column(nullable = false) private Integer stock;

@Column(length = 100) private String category;

@Column(name = “create_time”) private LocalDateTime createTime;

@Column(name = “update_time”) private LocalDateTime updateTime;

@PrePersist protected void onCreate() { createTime = LocalDateTime.now(); updateTime = LocalDateTime.now(); }

@PreUpdate protected void onUpdate() { updateTime = LocalDateTime.now(); } }

第二步,让AI生成Repository层。

调用AgentService:

AgentRequest repoRequest = new AgentRequest(); repoRequest.setRequirement(“请为Product实体生成一个JPA Repository,支持以下查询:1.按名称模糊搜索 2.按分类查询 3.按价格范围查询 4.按库存小于指定数量的查询 5.支持分页和排序”); repoRequest.setTargetFile(“repository/ProductRepository.java”); repoRequest.setContextCode(读取Product.java的内容);

AI返回的ProductRepository代码(经过我实际验证和调整):

@Repository public interface ProductRepository extends JpaRepository<Product, Long> {

@Query(“SELECT p FROM Product p WHERE p.name LIKE %:keyword%”) Page searchByName(@Param(“keyword”) String keyword, Pageable pageable);

Page findByCategory(String category, Pageable pageable);

@Query(“SELECT p FROM Product p WHERE p.price BETWEEN :minPrice AND :maxPrice”) Page findByPriceRange(@Param(“minPrice”) BigDecimal minPrice, @Param(“maxPrice”) BigDecimal maxPrice, Pageable pageable);

@Query(“SELECT p FROM Product p WHERE p.stock < :threshold”) List findLowStock(@Param(“threshold”) Integer threshold); }

第三步,让AI生成Service层。

public class ProductService {

@Autowired private ProductRepository productRepository;

public Product createProduct(CreateProductRequest request) { // 重复名称检查 if (productRepository.findByName(request.getName()).isPresent()) { throw new BusinessException(“商品名称已存在”); }

Product product = new Product();
product.setName(request.getName());
product.setDescription(request.getDescription());
product.setPrice(request.getPrice());
product.setStock(request.getStock());
product.setCategory(request.getCategory());

return productRepository.save(product);

}

public Page searchProducts(String keyword, String category, BigDecimal minPrice, BigDecimal maxPrice, int page, int size) { Pageable pageable = PageRequest.of(page, size, Sort.by(“createTime”).descending());

// 这里简化了组合查询逻辑,实际项目建议用Specification或QueryDSL
if (keyword != null && !keyword.isEmpty()) {
return productRepository.searchByName(keyword, pageable);
}
if (category != null && !category.isEmpty()) {
return productRepository.findByCategory(category, pageable);
}
if (minPrice != null && maxPrice != null) {
return productRepository.findByPriceRange(minPrice, maxPrice, pageable);
}

return productRepository.findAll(pageable);

}

public Product updateProduct(Long id, UpdateProductRequest request) { Product product = productRepository.findById(id) .orElseThrow(() -> new BusinessException(“商品不存在”));

// 只更新非null字段
if (request.getName() != null) product.setName(request.getName());
if (request.getDescription() != null) product.setDescription(request.getDescription());
if (request.getPrice() != null) product.setPrice(request.getPrice());
if (request.getStock() != null) product.setStock(request.getStock());
if (request.getCategory() != null) product.setCategory(request.getCategory());

return productRepository.save(product);

}

@Transactional public void deleteProduct(Long id) { if (!productRepository.existsById(id)) { throw new BusinessException(“商品不存在”); } productRepository.deleteById(id); } }

第四步,让AI生成Controller层并自动写测试。

Controller代码如下(核心逻辑,import已省略):

@RestController @RequestMapping(“/api/products”) public class ProductController {

@Autowired private ProductService productService;

@PostMapping public ResponseEntity create(@RequestBody CreateProductRequest request) { return ResponseEntity.ok(productService.createProduct(request)); }

@GetMapping public ResponseEntity<Page> search( @RequestParam(required = false) String keyword, @RequestParam(required = false) String category, @RequestParam(required = false) BigDecimal minPrice, @RequestParam(required = false) BigDecimal maxPrice, @RequestParam(defaultValue = “0”) int page, @RequestParam(defaultValue = “20”) int size) { return ResponseEntity.ok( productService.searchProducts(keyword, category, minPrice, maxPrice, page, size) ); }

@PutMapping(“/{id}”) public ResponseEntity update(@PathVariable Long id, @RequestBody UpdateProductRequest request) { return ResponseEntity.ok(productService.updateProduct(id, request)); }

@DeleteMapping(“/{id}”) public ResponseEntity delete(@PathVariable Long id) { productService.deleteProduct(id); return ResponseEntity.noContent().build(); } }

到这里,一个完整的商品管理CRUD模块就通过AI Agent生成了。从实体定义到Controller接口,全过程不需要手动写重复代码。

五、踩坑记录:3个你可能也会遇到 经过了几个项目的实际使用,几个关键的注意点。

第一,AI生成的JPA查询方法名有时会偏离Spring Data的命名规范。比如它可能生成findByProductName而不是findByName,如果不加@Query直接运行会报NoSuchPropertyException。建议用的时候先让AI确认方法名对应的SQL逻辑,不确定的加上@Query注解。

第二,事务边界要手动补。AI生成的Service方法经常忘记加@Transactional。这在简单场景没事,但一旦涉及多表操作或者删除后需要做级联操作,缺少事务会导致数据不一致。建议在Service类上统一加@Transactional注解。

第三,Controller的参数校验经常漏。AI不会自动给Request类加@NotNull、@NotBlank、@Min等校验注解。用户传了一个负数价格或者空字符串商品名进来,Service层的代码直接就存进数据库了。建议在Request类上加Spring Validation的注解,Controller方法参数前加@Valid。

六、总结 这篇文章搭了一个最小可用的Spring Boot加AI Agent架构。总结几个核心要点。

架构上,项目扫描、代码生成、文件写入三个模块解耦,方便后续替换AI服务或者扩展功能。流程上,AI负责生成代码,你负责审查和决策。给AI的Prompt里要包含项目上下文(现有代码、依赖信息),否则生成的代码和你项目对不上。

安全上,AI生成的代码必须经过人工审查(参考我上一篇文章的7个检查项),涉及数据库和文件系统的操作尤其要小心。业务规则、边界条件、线程安全这三块是AI最容易出错的地方。

后续可以扩展的方向。让AI读取整个项目的类结构和依赖关系,提供更精准的上下文。加入代码质量和安全扫描,AI生成的代码自动跑SonarQube。加入多Agent协作,一个Agent写Service层、一个Agent写Controller层、一个Agent写测试。

如果你也在用Spring Boot做项目,建议照着这篇文章的架构搭一套试试。第一次搭可能花半天,但搭好之后每次开发新模块能省掉大量重复代码的编写时间。

赞(0)
未经允许不得转载:171主机测评 » Spring Boot 3.3 + AI Agent 实战:从API调用到智能代码生成,手把手带你落地
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址