Spring AI 2.0 升级指南:从 1.x 平滑迁移的 Breaking Changes 全清单 + 改造清单
系列:Spring AI 深入浅出(第 4 篇)
版本:Spring AI 1.0/1.1 → 2.0.1 / Spring Boot 4.1.x / JDK 21
标签:#SpringAI2.0 #升级指南 #SpringAI迁移 #breakingChanges
前置阅读:第 1 篇《五分钟跑通第一个应用》
预计字数:7000 字|可复制迁移 diff + 对照表 + 踩坑 FAQ
本文将解决:从 Spring AI 1.x 升到 2.0不是改个版本号——Boot、JDK、Jackson、ChatClient 职责、ChatMemory、MCP 传输层都动了。本文给你一份"照着改就行"的 breaking changes 清单和最小升级 diff。
你将学到:
- 2.0 为什么是 breaking 大版本(底座 + 框架双重重构)
- 底座迁移:Boot 3→4、JDK 17→21、
javax.*→jakarta.*、Jackson 2→3 - 依赖坐标变化(含 Azure OpenAI starter 的移除)
- API 迁移:ChatClient 职责、Options Builder 模式、ChatMemory 变化
- MCP 传输层 SSE → Streamable HTTP 的调整
- 一个可直接对照的 1.x vs 2.0 最小 diff
一、版本标注
本文是系列里唯一的"对照篇":讲的是1.x → 2.0的迁移,2.0 侧以 2.0.1 为准。如果你还停在 1.x,这篇正好;如果你全新上手 2.0,看第 1~3 篇即可。
二、为什么 2.0 是 breaking 大版本
2.0 的 breaking 来自两条线叠加:
- 底座大版本:对齐 Spring Boot 4 / Spring Framework 7 的升级,这本身就带来 JDK、Jakarta、Jackson 的连锁升级。
- 框架自身重构:ChatClient/ChatModel 职责重定位、Options 统一 Builder、工具调用循环重写、MCP 传输层换代。
结论:1.x → 2.0 必须作为一次正式升级来对待,不能只改 pom 里的版本号。
三、底座迁移(先改环境,再改代码)
| 项 | 1.x | 2.0 | 改法 |
|---|---|---|---|
| Spring Boot | 3.4/3.5 | 4.0/4.1 | 父工程版本升级 |
| JDK | 17 | 21+ | 升级 JDK 并改java.version |
| Jakarta | 已用jakarta.* | 继续jakarta.*(EE 11) | 基本无感,注意个别包 |
| Jackson | Jackson 2 | Jackson 3 | 自定义序列化器要排查 |
最容易翻车的是 Jackson 2→3:如果你项目里有自定义的ObjectMapper、序列化器、@JsonIgnore等,升级后可能出现行为差异或编译错误,需要逐一排查(本系列第 8 篇讲结构化输出时会再展开)。
四、依赖坐标变化
4.1 BOM 与 Boot 版本
<!-- 1.x --><properties><java.version>17</java.version><spring-ai.version>1.0.0</spring-ai.version></properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.5.0</version></parent><!-- 2.0 --><properties><java.version>21</java.version><spring-ai.version>2.0.1</spring-ai.version></properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>4.1.0</version></parent>4.2 starter 命名
主流的spring-ai-starter-model-openai命名在 1.0/2.0 之间没变(真正废弃的是 1.0 之前的spring-ai-openai-spring-boot-starter旧名)。但有一处要特别注意:
spring-ai-starter-model-azure-openai在 2.0 已移除。接 Azure OpenAI 不再用专用 starter,改用 OpenAI starter 配 Azure 的 base-url 与 api-key。
五、API 迁移清单(核心)
5.1 ChatClient 职责重定位
2.0 明确了ChatClient(业务/Agent 主入口)与ChatModel(框架底层接口)的分工。业务代码里不要直接依赖ChatModel手动拼请求,统一走ChatClient:
// 1.x 常见写法(直接操作 ChatModel)ChatResponseresp=chatModel.call(newPrompt("..."));// 2.0 推荐写法(走 ChatClient)Stringreply=chatClient.prompt().user("...").call().content();5.2 Options 统一 Builder 模式
1.x 的 Options 存在冗余的.options嵌套层级,2.0 统一成不可变的 Builder 模式:
// 1.x:可变 setter 风格(示意)OpenAiChatOptionsoptions=newOpenAiChatOptions();options.setTemperature(0.3);// 2.0:Builder 模式,创建后不可变ChatOptionsoptions=ChatOptions.builder().model("gpt-4o-mini").temperature(0.3).maxTokens(1024).build();配置侧也对应扁平化:1.x 的spring.ai.openai.chat.options.model这类嵌套,在 2.0 有调整。稳妥做法是把 model/temperature 放到 Java 侧ChatOptions.builder()(本系列所有代码都这么写),配置里只留api-key和base-url。
5.3 ChatMemory 变化(重点,最容易编译报错)
2.0 对记忆相关 API 做了三处 breaking:
// ① InMemoryChatMemory 已移除 → 用 MessageWindowChatMemory.builder()// 1.xChatMemorymemory=newInMemoryChatMemory();// 2.0ChatMemorymemory=MessageWindowChatMemory.builder().build();// ② MessageChatMemoryAdvisor 改为 Builder 模式// 1.xnewMessageChatMemoryAdvisor(chatMemory);// 2.0MessageChatMemoryAdvisor.builder(chatMemory).build();// ③ ChatMemory.DEFAULT_CONVERSATION_ID 已删除 → 会话 id 必须显式传chatClient.prompt().advisors(a->a.param(ChatMemory.CONVERSATION_ID,conversationId)).user(q).call().content();第三处最隐蔽:1.x 里不传 conversationId 会用一个默认值兜底,2.0删掉了这个默认值,不传会导致多用户串话。升级后务必在每个记忆请求上显式传 conversationId。
5.4 其他 API 微调
- 工具调用循环从各
ChatModel内部提升为递归 Advisor 链(ToolCallingAdvisor),自定义工具回调的接线方式有变化(详见第 13/14 篇)。 - 部分
@Tool相关注解与参数校验有调整,升级后重新核对工具定义。
六、MCP 传输层调整(SSE → Streamable HTTP)
1.x 里 MCP 默认走 SSE 传输,2.0 升级到 MCP 2.0:Streamable HTTP 成为默认传输,SSE 被弃用。
- 如果你的 MCP 客户端/服务端是 1.x 搭的,升级后要检查传输层配置,改为 Streamable HTTP。
- STDIO 仍保留(用于本地进程)。
- 2.0 新增
@McpTool/@McpResource/@McpPrompt注解驱动开发(详见第 15 篇)。
七、最小升级 diff(可直接对照)
同一个"问一句答一句"功能,1.x 与 2.0 的完整差异:
pom.xml:改java.version(17→21)、spring-ai.version(1.0→2.0.1)、父工程 Boot(3.5→4.1)。
application.yml:基本不变,仍用spring.ai.openai.api-key/base-url,model 建议移到代码侧。
Java:
// 业务代码几乎不变,仍走 ChatClientStringreply=chatClient.prompt().user(q).call().content();真正的改动集中在:① 记忆相关 API(5.3 三处)② Options 用 Builder ③ 自定义工具/MCP 接线。
八、原理图解:1.x vs 2.0 架构对照
核心变化:横切能力(工具、记忆、检索)从"藏在 ChatModel 里"移到"递归 Advisor 链"上,这是 2.0 最重要的架构升级,也是理解后续所有高级能力的关键。
九、踩坑 FAQ
坑 1:只升 spring-ai 版本,Boot 还是 3.x
现象:把spring-ai改成 2.0,Boot 仍 3.x,启动报大量兼容错。
原因:Spring AI 2.0 依赖 Boot 4,和 Boot 3 不兼容。
解决:Boot 和 Spring AI一起升(Boot 4.1 + Spring AI 2.0.1),或都停在 1.x。
坑 2:升级后InMemoryChatMemory编译不过
现象:new InMemoryChatMemory()报类不存在。
原因:2.0 已移除该类。
解决:改用MessageWindowChatMemory.builder().build()。
坑 3:多用户对话升级后串话
现象:升级到 2.0 后,不同用户的对话互相串了。
原因:ChatMemory.DEFAULT_CONVERSATION_ID被删除,不传 conversationId 就没有隔离。
解决:每个记忆请求显式传 conversationId(见 5.3 第③点)。
坑 4:自定义 Jackson 序列化失效
现象:升级后自定义的ObjectMapper/序列化器行为不对。
原因:Jackson 2 → 3 的升级。
解决:排查自定义序列化代码,适配 Jackson 3;AI 序列化底座已提供统一的JsonMapper/JsonHelper。
坑 5:MCP 连不上(还在用 SSE)
现象:升级后 MCP 客户端/服务端连不上。
原因:2.0 默认传输从 SSE 换成 Streamable HTTP。
解决:改传输层配置为 Streamable HTTP(详见第 15 篇)。
十、小结与合集导航
2.0 的迁移核心就一句:先升底座(Boot 4 + JDK 21),再改记忆 API 三处,最后核对 Options Builder 与 MCP 传输层。
- 底座:Boot 3→4、JDK 17→21、Jackson 2→3
- 依赖:BOM 2.0.1,Azure starter 移除
- API:ChatMemory 三处 breaking 是编译报错高发区
- MCP:SSE → Streamable HTTP
下一篇:《别把 Prompt 硬编码进代码》——进入核心抽象层,讲提示词的工程化管理。
十一、互动钩子
投票:你现在 Spring AI 用哪个版本?
- 还在 1.x,准备升 2.0
- 已经在 2.0
- 还没开始用
评论区聊聊你迁移踩的坑,我会精选有代表性的坑补充进本文 FAQ;源码见置顶评论。