Java 25 发了但更让我兴奋的是这个:Spring AI 让 Java 调大模型终于不用手写 HTTP 了
作者:互联网
2026-03-22
昨天刷掘金满屏都是 Java 25,什么 Pattern Matching、Stable Values、Module Import... 说实话这些特性确实不错,但作为一个每天都在调 AI API 的后端仔,让我更兴奋的反而是另一件事——Spring AI 终于把 Java 调大模型这件事做对了。
之前用 Java 调 GPT、Claude 这些模型,要么手写 OkHttp/RestTemplate 拼 JSON,要么用一堆非官方 SDK 担心跑路。现在 Spring AI 1.0 GA 了,配合 Java 25 的新语法糖,体验直接拉满。
先说结论
| 对比项 | 手写 HTTP | Python openai 库 | Spring AI 1.0 |
|---|---|---|---|
| 接入成本 | 高(拼 JSON、处理流式) | 低(3 行代码) | 低(3 行配置) |
| 类型安全 | 无 | 无 | 有(编译期检查) |
| 切换模型 | 改一堆代码 | 改 model 参数 | 改一行配置 |
| 切换厂商 | 重写 | 改 base_url | 改一行配置 |
| 流式响应 | 手动处理 SSE | 简单 | Flux 原生支持 |
| Spring 生态集成 | 自己搞 | 不存在 | 原生(DI、AOP、配置中心) |
一句话:Java 调大模型的体验,终于追上 Python 了。某些方面甚至更好。
从 0 到跑通:10 分钟搞定
第一步:建项目
Java 25 + Spring Boot 3.5 + Spring AI 1.0,用 start.spring.io 勾一下就行。如果你习惯手动搞,pom.xml 加这些:
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>3.5.0version>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.aigroupId>
<artifactId>spring-ai-openai-spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.aigroupId>
<artifactId>spring-ai-bomartifactId>
<version>1.0.0version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
第二步:配置(重点来了)
application.yml 只需要 3 行:
spring:
ai:
openai:
api-key: ${AI_API_KEY}
base-url:
chat:
options:
model: gpt-5-mini
temperature: 0.7
这里的关键在于 base-url——Spring AI 用的是 OpenAI 兼容协议,意味着任何兼容 OpenAI 协议的服务都能直接用。后面会细说这个。
第三步:写代码
@RestController
public class ChatController {
private final ChatClient chatClient;
public ChatController(ChatClient.Builder builder) {
this.chatClient = builder.build();
}
@GetMapping("/chat")
public String chat(@RequestParam String message) {
return chatClient.prompt()
.user(message)
.call()
.content();
}
}
没了。不是简化版,这就是完整代码。跑起来访问 /chat?message=你好 就能拿到 AI 回复。
要是之前用 OkHttp 写,光拼请求体、解析响应就得 50 行起步,还得处理各种边界情况。
Java 25 新语法 + Spring AI 的化学反应
Java 25 的几个新特性和 Spring AI 配合起来特别舒服。
Pattern Matching 处理多模型响应
// Java 25 的增强 Pattern Matching,处理不同类型的 AI 响应
public String handleResponse(Generation generation) {
var result = generation.getResult();
return switch (result) {
case AssistantMessage msg when msg.hasToolCalls() ->
processToolCalls(msg.getToolCalls());
case AssistantMessage msg when msg.getContent().length() > 5000 ->
summarize(msg.getContent());
case AssistantMessage msg ->
msg.getContent();
default -> "未知响应类型";
};
}
比起之前的 if-else 嵌套,这个可读性好太多了。
Record + Structured Output = 类型安全的 AI 输出
这是我觉得 Spring AI 最香的功能——结构化输出。配合 Java 的 Record 类型:
// 定义你想要的输出结构
record CodeReview(
String summary,
List issues,
int score
) {
record Issue(String file, int line, String severity, String description) {}
}
// AI 直接返回强类型对象,不用手动 parse JSON
@GetMapping("/review")
public CodeReview reviewCode(@RequestParam String code) {
return chatClient.prompt()
.user("Review this code and identify issues:n" + code)
.call()
.entity(CodeReview.class);
}
返回值直接就是 CodeReview 对象,Spring AI 在底层帮你把 AI 的 JSON 输出反序列化成强类型。如果 AI 返回的格式不对,它会自动重试。
这在 Python 里得用 Pydantic + instructor 才能做到,Java 原生 Record 就够了。
实战:3 个真实场景
场景 1:智能客服(流式输出)
@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux streamChat(@RequestParam String message) {
return chatClient.prompt()
.system("你是一个专业的客服助手,回答要简洁准确")
.user(message)
.stream()
.content();
}
前端用 EventSource 接收就行,打字机效果直接就有了。底层走的是 Reactor 的 Flux,和 Spring WebFlux 天然集成,不用自己搞 SSE。
场景 2:批量文档摘要(并发优化)
@Service
public class DocumentSummarizer {
private final ChatClient chatClient;
public List summarizeBatch(List documents) {
return documents.parallelStream()
.map(doc -> chatClient.prompt()
.user("用一句话总结这段文档:n" + doc)
.call()
.content())
.toList();
}
}
Java 25 的虚拟线程加持下,parallelStream 跑 AI 调用不会阻塞平台线程。100 个文档并发摘要,线程池都不用配。
场景 3:Function Calling(让 AI 调你的 API)
@Bean
@Description("查询指定城市的实时天气")
public Function getWeather() {
return request -> weatherService.query(request.city());
}
record WeatherRequest(String city) {}
record WeatherResponse(String city, double temp, String condition) {}
注册一个 Bean,加个 @Description 注解,Spring AI 就会自动把这个函数暴露给大模型。用户问"北京今天天气怎么样",AI 会自动调用 getWeather("北京"),拿到结果后再组织语言回复。
这个功能之前要手写一堆 JSON Schema 描述,现在 Spring AI 从 Record 的字段名自动推断,省了一大坨模板代码。
踩坑记录
坑 1:OpenAI 官方 API 在国内延迟感人
测试环境用 OpenAI 官方 API 没问题,但上了国内服务器后首 token 延迟 3-8 秒,流式输出断断续续。
解决办法:换一个兼容 OpenAI 协议的国内接口。Spring AI 的好处就在这——只改配置,代码一行不动:
spring:
ai:
openai:
api-key: ${OFOX_API_KEY}
base-url:
chat:
options:
model: gpt-5-mini
改完 base-url 和 api-key 就行了。我用 ofox.ai 的聚合接口测了一下,首 token 延迟从 5 秒降到了 300ms 左右,而且同一套配置可以切 GPT、Claude、Gemini 各种模型,不用换 SDK。
坑 2:Structured Output 偶尔解析失败
AI 返回的 JSON 有时候会多一些字段或者格式不对,导致反序列化失败。Spring AI 默认会重试一次,但如果你的 Record 定义比较复杂,建议加个 @JsonIgnoreProperties(ignoreUnknown = true):
@JsonIgnoreProperties(ignoreUnknown = true)
record CodeReview(String summary, List issues, int score) {
// ...
}
坑 3:Spring AI 的 BOM 版本别搞混
Spring AI 1.0.x 和 Spring Boot 3.5.x 配套使用。如果你还在 Spring Boot 3.3,需要用 Spring AI 0.8.x。版本不匹配会报一堆 NoSuchMethodError,debug 到怀疑人生。
坑 4:流式输出的错误处理
stream() 返回的 Flux 如果中途 AI 报错,默认会直接断掉连接。建议加个 onErrorResume:
return chatClient.prompt()
.user(message)
.stream()
.content()
.onErrorResume(e -> Flux.just("[AI 响应异常,请重试]"));
和 Python 方案的对比
说实话,写这篇文章之前我一直觉得 Java 调 AI 不如 Python 方便。但实际用下来,Spring AI 在几个方面甚至超过了 Python:
- 类型安全:Record + Structured Output 比 Pydantic 更简洁
- 并发能力:虚拟线程 + Reactor 碾压 Python 的 asyncio
- 工程化:配置中心、健康检查、指标监控全是现成的
- 切换厂商:改一行 YAML 配置 vs Python 里可能要换 SDK
Python 赢在原型速度——写个脚本调一下 API,Python 确实更快。但一旦要上生产、要维护,Java + Spring AI 的工程化优势就出来了。
小结
Java 25 + Spring AI 1.0 这个组合确实让 Java 在 AI 开发领域翻身了。以前 Java 同学看 Python 同学三行代码调 GPT 只能流口水,现在 Java 也是三行配置的事。
而且 Spring AI 最聪明的设计是用 OpenAI 兼容协议做底层——你今天用 GPT,明天想换 Claude 或者国产模型,改一行配置就行,代码完全不动。这对企业项目来说太重要了。
如果你是 Java 开发者,强烈建议现在就试试 Spring AI。真不是让你放弃 Python,而是该用 Java 的场景终于不用为了调个 AI 硬切 Python 了。
相关推荐
专题
+ 收藏
+ 收藏
+ 收藏
+ 收藏
+ 收藏
最新数据
相关文章
拒绝硬编码!利用 Java SPI 打造一个可插拔的代码解析器
给 Spring Boot 接口加了幂等保护:Token 机制 + 结果缓存,一个注解搞定
一站式了解接口防刷(限流)的基本操作
ThreadForge v1.1.0 发布:让 Java 并发更接近 Go 的开发体验
各版本JDK对比:JDK 21 特性详解
JVM 内存溢出排查
LangChain4j Prompt 提示词工程
彻底重绘Spring Boot性能版图,资源占用缩减80%
百度智能云模型接入
CompletableFuture深度解析:异步编程与任务编排的实现
AI精选
