前两天刷技术社区,看到一条动态说 Spring AI Alibaba 的提交记录已经停在很久之前,评论区瞬间就炸了。一半人在惋惜一个背靠大厂的 Java AI 脚手架就这么凉了,另一半人直接抛出一个大命题:Java 是不是真的被 AI 时代抛弃了?这个问题最近我被问过不下十次,干脆写篇文章把它掰开聊清楚。
先说结论:Spring AI Alibaba 停更,确实是个事实,但它能不能代表“Java 没希望”,这完全是两个维度的问题。我不打算站队,也不贩卖焦虑,就用一个普通后端开发者的视角,把事实、原理、替代方案、实际代码都摆出来。这篇文章适合所有用 Java 做后端、看到 AI 浪潮心慌的开发者,也适合刚准备入行、在语言选择上犹豫的朋友。
1. 先说清楚:Spring AI Alibaba “停更”到底停了什么
1.1 停更不等于项目立刻“死了”
Spring AI Alibaba 是什么?简单说,它是阿里巴巴围绕 Spring AI 做的一个增强发行包。Spring AI 是 Spring 官方出的 AI 应用开发框架,而 Spring AI Alibaba 主要补的是阿里系大模型(通义系列)的接入适配,以及一些面向云原生环境的集成能力。
“停更”在开源世界里的准确含义是:这个仓库不再有新的版本发布,GitHub 上的 issues 很久没人回复,提交记录停在某个时间点不再往前走了。注意,这不是“项目被清空”,也不是“代码跑不了了”。仓库还在,已经发出去的 jar 包还在 Maven 中央仓库里躺着,你现有项目里锁定的版本不会自己消失,也不会自己变坏。
我在公司里经常会用一个类比:这就好比你当年找装修队装好的房子,水电、瓷砖、柜子都是验收过的,住着完全没问题。但装修队撤场了,你想再加一个房间,或者让原来的风格升级换代,那就没人管了。Spring AI Alibaba 停更,对已经在用它的项目来说,短期就是“凑合能用”,长期是“后面的事都得自己来”。
1.2 一个背靠大厂的项目,为什么会走到停更这一步
很多人不理解:阿里巴巴的资源摆在那,为什么说不维护就不维护了?我从技术演进的规律来分析,无非是这几个原因叠加。
第一,官方 Spring AI 本身在快速成熟。Spring 官方对 AI 框架投入很大,它在不断吸收生态里的优秀设计,统一的消息、工具调用、向量存储抽象都在完善。当官方框架覆盖了大部分能力时,一个“二次开发”的发行版就失去了存在的必要性。不是没有人用,而是它的差异化价值在缩水。
第二,云厂商的 SDK 策略通常跟着模型和平台商业化走。这类项目往往承担着“引流”作用,当集团内部的模型策略、商业化方向调整,对应的开源组件优先级自然就会下降。
第三,社区型项目的通病:核心维护者精力转移。一个大型组织里,某个项目能不能持续,很大程度上取决于有没有固定的团队长期背书。一旦精力被抽走,项目就进入“半休眠”状态。
我特意说这些,是想让你明白:停更这件事本身不带什么悲壮色彩,它就是开源生态里的自然选择,跟“Java 行不行”完全不是一回事。
1.3 停更对存量项目的实际影响:一张风险清单
如果你手头已经有项目用了 Spring AI Alibaba,这张表你可以对照着看:
| 影响领域 | 短期(1年内) | 长期(2年以上) |
|---|---|---|
| 依赖稳定性 | 已发布 jar 正常可用 | 新功能缺失,问题没人修 |
| 新模型适配 | 老模型接口基本可用 | 阿里新模型无法简单接入 |
| 安全漏洞 | 暂时未爆出严重漏洞 | 无官方补丁,风险靠自查 |
| 版本升级 | 保持现状可以 | 升级 Spring Boot/Spring AI 时可能冲突 |
| 社区支持 | issues 无人回应 | 踩坑只能靠自己和搜索引擎 |
看完这张表你就知道,真正致命的从来不是“框架死了”,而是“框架死了但你的业务还在继续长”。所以接下来的重点不是哀悼,而是想想后面的路怎么走。
2. 焦虑的根源:大家把“AI”等同于“Python 训练模型”,这是理解偏差
2.1 Python 在 AI 训练生态的统治地位从哪来
Java 开发者最焦虑的参照物,就是 Python。你看所有深度学习框架——接口、模型权重、数据预处理工具、论文附带代码,几乎全是 Python 优先。做训练、做实验、做微调的研究人员和算法工程师,用 Python 是顺理成章的。
这也导致了技术社区里一种很强的刻板印象:AI = Python。似乎你想在这波浪潮里分一杯羹,就得去写 Python,否则你就是旁观者。这个印象不完全是错的,但它只描述了 AI 产业链的上游——模型生产环节。
2.2 但企业级 AI 落地的主战场不是训练,是“接线”
模型生产出来之后,怎么变成业务价值?这一步需要大量工程化工作:鉴权、限流、参数处理、结果解析、业务逻辑编排、事务管理、幂等控制、数据入库、工单流转、与现有系统打通……这些工作的本质是“把大模型这条线,接到你现有的业务电路板上”。而这一层,恰恰是 Java 后端十几年积累下来的舒适区。
我自己做过的一个客服知识问答系统非常典型。模型用的是外部大模型 API,但整个系统的重心根本不在“调模型”上,而在知识库管理、用户权限隔离、工单联动、消息推送、对账统计这些 Java 后端常规能力上。这个项目里,Java 代码占了 90% 以上,大模型只是一个被调用的能力组件。
2.3 回到现实:大多数业务并不需要自建大模型
需要冷静面对一个事实:全世界几千万家公司,真正自研大模型的比例微乎其微。绝大多数业务场景是调用成熟模型 API:开源模型也罢、商业模型也罢,总归是通过 HTTP 接口去调用。模型托管在 GPU 集群里,你这边只需要发请求、收结果。
这类开发的难度不在“AI 算法”,而在工程:怎么管理上下文、怎么做检索增强、怎么让模型输出的结构化结果稳定落到业务流程里。这些能力 Java 完全做得动,而且在大规模、高并发、强事务场景下,Java 的成熟度可能比 Python 那一套 Web 框架还要高出一截。
所以你说 Java 有没有希望?你要是在焦虑“Java 能不能训练出下一代大模型”,那答案是确实不太行,但那是算法工程师和 GPU 集群该操心的事,不是后端开发者的主战场。
3. Java 在 AI 应用层能干的活:对话、RAG、Agent 逐个拆开看
3.1 对话与多轮记忆:本质是消息状态管理
你调大模型 API 的时候,模型本身是无状态的。每轮对话,你需要把历史消息拼成一个消息列表发给它,它看到的是完整的会话上下文。这就是多轮对话的全部秘密。
Spring AI 把这块抽象成了 ChatClient 和消息历史管理,但在它之前,纯手工也能做,无非是你自己维护一个 List ,控制一下总 token 数,超出窗口就把最早的消息丢掉。Java 做这件事非常顺手,因为内存数据结构、序列化、列表操作都是基本功。很多同学担心“AI 对话很玄”,其实去掉模型返回的随机性,剩下就是一套比较常规的消息流水线。
3.2 RAG 知识库:Java 不是没能力,是入口比较散
RAG(检索增强生成)是目前企业落地 AI 最实在的方向:把企业内部的文档、知识库切成片段,向量化存储;用户提问时先做语义检索,把候选片段拼进提示词,再让模型基于这些材料回答。这样比让模型凭空生成靠谱得多,还能减少幻觉。
这套流程拆开看,每个环节 Java 都能干:
- 文档解析:PDF、Word、Markdown 都有 Java 解析库,把文本提取出来;
- 文本切分:按段落、按 token 数、按语义边界切成 chunk,这一步是核心调参点;
- Embedding 向量化:调用 embedding 模型的 HTTP 接口,Java 发个请求就能拿向量;
- 向量存储:PostgreSQL + pgvector、Redis 向量检索、Elasticsearch/OpenSearch 都能用;
- 语义检索:算出用户问题的向量,查 top K 相似片段;
- 拼装提示词:把检索出来的片段按模板塞进大模型请求里。
这里面没有任何一个环节要求你必须用 Python。Spring AI 和 LangChain4j 都已经把这些能力组件化了,VectorStore 抽象帮你屏蔽了后端差异,上面贴一套 pgvector,下面换 Elasticsearch,业务代码几乎不用动。
3.3 Agent 与函数调用:Java 的强项被低估了
再说 Agent(智能体),很多人觉得这是 Python 的天下。但实际上,Agent 的核心机制是 Function Calling(函数调用):模型在对话过程中判断需要调用某个工具,就输出一段结构化的 JSON,里面包含函数名和参数;你的后端解析 JSON,执行对应函数,把结果再喂回给模型。
你细想一下这件事:这个“对应函数”放在 Java 里是什么?就是普通的方法而已。Spring 容器管理这些 Bean 的依赖注入、事务、权限,写起来再顺手不过。你甚至可以给方法加一个 @Tool 注解,让 AI 框架自动把它包装成一个“可被模型调用的工具”。
我做过一个内部工单助手,把查询订单、更新状态、分配处理人等操作都暴露成 Agent 工具。结果发现,真正花时间的地方不是“让模型调用工具”,而是让这些工具方法在事务边界、权限校验、幂等控制下安全执行——这不就是 Java 后端每天在做的事吗?
4. Spring AI Alibaba 停更之后,Java AI 路线怎么选:三条实测路径
4.1 主线路:跟随官方 Spring AI
Spring AI 是 Spring 官方出品,活跃度目前是 Java AI 框架里最高的。它和 Spring Boot 深度融合,提供了 ChatClient、PromptTemplate、VectorStore、Model API 等全套抽象,官网示例也越来越多。
优点很明显:版本迭代快、组件全、和你的 Spring 技术栈无缝衔接。缺点也得说清楚:版本 Beta 气息还比较重,升级时经常有破坏性变更,很多 API 这个版本写法和下个版本不一样。所以选这条路,你要做好“追新版本”的准备。
适合什么项目?新启动的项目,团队愿意跟进社区节奏,可以拿它快速验证。我不建议生产项目一上来就用最新版,等它稳定的小版本跑一两周再考虑升级。
4.2 支线路:LangChain4j 承担更复杂的 AI 编排
LangChain4j 是 Java 生态里的 LangChain 风格框架,它比 Spring AI 更早开始构建比较完整的“Agent 原语”:多模型适配、Prompt 模板、对话记忆、工具调用、输出解析器,还有一套比较灵活的 AI 服务注解。如果你要做的不是简单问答,而是多步骤推理、带工具的智能体,LangChain4j 的抽象会让你省不少事。
但它的缺点也很真实:社区体量比 Spring AI 小,踩坑时能搜到的案例少;和 Spring Boot 的集成不像官方框架那么“原生”,需要你自己多写一点胶水代码。
4.3 底线路:裸调模型 API + 自研薄封装
这是我自己最常用的路线。核心思路是:不依赖任何 AI 专用 SDK,只用 Spring Boot 自带的 HTTP 客户端去调大模型 API,然后自己包一层接口。
优点最突出:依赖最少、可控性最高、老项目完全不用为此升级一堆依赖。模型服务商换一个,你只需要改配置或换一个实现类,业务层无感知。缺点也很直接:消息历史管理、工具调用协议、向量化集成这些都得自己写一部分,工作量会增加。
三条路线怎么选,我整理了一张对比表:
| 对比维度 | 官方 Spring AI | LangChain4j | 自研薄封装 |
|---|---|---|---|
| 社区活跃度 | 高 | 中 | 不依赖社区 |
| 上手难度 | 低(有官方示例) | 中(概念多) | 中(自己要写封装) |
| 依赖轻量程度 | 中等 | 中等 | 最轻 |
| 复杂 Agent 支持 | 在完善 | 比较强 | 自己造轮子 |
| 生产可控性 | 中(版本变更快) | 中 | 高 |
我的建议是:如果你在选型,先别急着押注某一个,用三天时间把三条路线的 hello world 都跑一遍,你对它们的真实感觉会告诉你答案。
5. 一套不依赖停更 SDK 的 Spring Boot 接入大模型 API 示例
接下来直接上干货。这套代码不依赖 Spring AI Alibaba,也不依赖任何市面上特定的 AI SDK,你只要有大模型服务的 API Key,把地址换成自己的就能跑。
5.1 最小工程配置
我用 Spring Boot 3.x + Java 17,依赖只需要一个 Web 启动器(需要流式响应时再加 WebFlux)。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>application.yml 里配置模型服务的相关参数:
llm: base-url: https://api.example.com/v1 api-key: ${LLM_API_KEY} model: qwen-plus timeout-seconds: 605.2 非流式调用:通用大模型客户端
先定义一个配置类,把参数读取进来,构建一个带有超时控制的 RestClient。这里用 Java 接口的 Pseudo-Typed API 风格。
@Component @ConfigurationProperties(prefix = "llm") public class LlmProperties { private String baseUrl; private String apiKey; private String model; private int timeoutSeconds; // getter / setter 省略 }然后写一个轻量客户端,核心逻辑是:拼消息、发请求、解析结果。
@Service public class LlmClient { private final RestClient restClient; private final LlmProperties props; public LlmClient(LlmProperties props) { this.props = props; this.restClient = RestClient.builder() .baseUrl(props.getBaseUrl()) .defaultHeader("Authorization", "Bearer " + props.getApiKey()) .requestFactory(new JdkClientHttpRequestFactory( HttpClient.newBuilder() .connectTimeout(Duration.ofSeconds(props.getTimeoutSeconds())) .build())) .build(); } public String chat(String systemPrompt, String userMessage) { Map<String, Object> requestBody = new HashMap<>(); requestBody.put("model", props.getModel()); List<Map<String, String>> messages = new ArrayList<>(); messages.add(Map.of("role", "system", "content", systemPrompt)); messages.add(Map.of("role", "user", "content", userMessage)); requestBody.put("messages", messages); Map<?, ?> response = restClient.post() .uri("/chat/completions") .contentType(MediaType.APPLICATION_JSON) .body(requestBody) .retrieve() .body(Map.class); // 提取 choices[0].message.content List<?> choices = (List<?>) response.get("choices"); Map<?, ?> firstChoice = (Map<?, ?>) choices.get(0); Map<?, ?> message = (Map<?, ?>) firstChoice.get("message"); return message.get("content").toString(); } }这段代码简单到几乎没有任何魔法,但它的好处是:你彻底掌握了自己发出的请求和收到的响应。模型协议变了,你改的是自己代码里的一处解析逻辑,不需要等 SDK 更新。
5.3 流式输出:SSE 场景的正确做法
对话式 AI 的一大体验点是“打字机效果”,也就是流式输出。后端接大模型的 SSE(Server-Sent Events)流再转发给前端,用 WebClient 做起来很自然。
@Service public class StreamService { private final WebClient webClient; private final LlmProperties props; public StreamService(LlmProperties props) { this.props = props; this.webClient = WebClient.builder() .baseUrl(props.getBaseUrl()) .defaultHeader("Authorization", "Bearer " + props.getApiKey()) .build(); } public Flux<String> streamChat(String userMessage) { Map<String, Object> body = new HashMap<>(); body.put("model", props.getModel()); body.put("stream", true); body.put("messages", List.of(Map.of("role", "user", "content", userMessage))); return webClient.post() .uri("/chat/completions") .contentType(MediaType.APPLICATION_JSON) .bodyValue(body) .retrieve() .bodyToFlux(String.class) .filter(line -> line.startsWith("data:")) .map(line -> { String json = line.substring(5).trim(); if ("[DONE]".equals(json)) { return ""; } // 这里解析 JSON,取出增量文本 JsonNode node = new ObjectMapper().readTree(json); JsonNode delta = node.path("choices").path(0).path("delta").path("content"); return delta.asText(""); }) .filter(text -> !text.isEmpty()); } }实操中要特别注意三点:一是大模型的 SSE 数据行很长,按行解析不要按块解析,不然会切碎;二是必须处理网络中断和超时,建议给 WebClient 配置响应超时并用重试策略兜底;三是流式场景的 token 计量比非流式更容易丢失,生产环境要在结束时汇总统计。
5.4 生产化必补的功课:七件容易漏的事
demo 能跑起来只是第一步。真上线,下面这七件事一个都别少。
- 重试与熔断。大模型 API 属于外部依赖,大概率会抖动。重试要控制次数和退避策略,熔断器可以用现成组件,别自己手写无限重试。
- 超时管理。连接超时、读取超时分开设置。流式接口的“首包时间”和“包间隔”比总时长更重要。
- 上下文裁剪。历史消息无限堆叠会超出窗口,要有按 token 数裁剪的策略。中文场景一个字大约 1 到 2 个 token,别按字符数硬算。
- 合规与安全过滤。用户输入里可能有提示注入、敏感内容。系统提示词要固定,用户内容要有过滤层,不能直接透传。
- Prompt 模板集中管理。不要在各种业务代码里拼字符串提示词。把模板放在统一资源里,线上想调整时不用重新发版。
- 模型版本隔离。不同业务场景用不同模型、不同超参。一个通用配置会互相影响。
- 日志留痕。记录每个请求的输入输出、token 消耗、模型响应时长,方便排查问题。
6. 别被“停更”带走节奏:Java 在 AI 时代的位置和打法
6.1 停更在开源世界是常态,核心是“抽象层”不能丢
说实话,搞 Java 这么多年,我们早就换过太多核心库了:数据库连接池从 C3P0 换到 Druid 再换到 HikariCP;HTTP 客户端从 HttpClient 换到 OkHttp 再换到 JDK 自带;JSON 库更是换了好几轮。每一次“某个项目不维护了”,业界都没慌过,因为大家知道技术选型可以换,但你自己的抽象层、业务理解、问题排查能力是换不掉的。
所以真正要反思的不是“Spring AI Alibaba 停更我好慌”,而是“我的项目是不是把命脉压在了某个 SDK 上,没有做隔离”。如果你的业务代码里直接 new 了 SDK 的类,业务方法里直接处理 SDK 特有对象,那停更确实会伤到你。但如果你的代码通过自己的接口调用模型能力,底层 SDK 换了,业务层纹丝不动。
6.2 给不同阶段的 Java 开发者的现实建议
如果你刚学 Java 没多久:别被“语言过时论”干扰。先把 JVM、集合、并发、Spring 这些基本功吃透。AI 框架更新再快,底层还是这些基础。你未来和 AI 结合的竞争力,是“你能把一个 AI 能力可靠地接入现有系统”,而不是“你会用某个最新脚手架”。
如果你是有经验的后端老手:该补的不是 Java,而是 AI 应用的基础知识。向量到底是什么、Embedding 怎么选、RAG 的切分和检索怎么调优、Function Calling 的协议怎么解析、token 怎么估算,这些是新的“领域知识”,掌握之后你会发现 Java 做它们毫无障碍。
如果你是团队技术决策者:选型上保留一条自研的“模型网关”路线或者“防腐层”。大模型供应商未来一定会频繁变化,不要把自己绑死在某一家、某一个 SDK 上。这也是我对 Spring AI Alibaba 停更事件最核心的反思。
6.3 我目前实际在用的方案:双轨制
聊点我自己的真实工作流。新项目快速原型我确实会用 Spring AI,因为它写 Demo 快,很多抽象能省时间。但生产项目我更倾向于走“薄封装”路线:定义一个 LlmGateway 接口,内部根据不同模型实现不同的 adapter。模型服务商、SDK 版本怎么变,网关接口不变,业务代码永远只依赖这个接口。
大致的结构是这样:
public interface LlmGateway { String chat(String prompt, ChatOptions options); Flux<String> streamChat(String prompt, ChatOptions options); } @Service public class QwenGateway implements LlmGateway { // 调阿里系模型,替换之前的 SDK 为 HTTP 直调 } @Service public class StandardOpenAiGateway implements LlmGateway { // 调 OpenAI 兼容协议模型 }如果哪天某个大模型服务突然不做了,或者某个 SDK 停更了,我要做的事情就是写一个新的 Gateway 实现,注册进来,切换一个配置。业务代码拿到的是 LlmGateway 接口,它连发生了什么都感知不到。
这样做的好处,在 Spring AI Alibaba 停更事件里体现得淋漓尽致:团队里有人说“完了,SDK 没了”,但项目代码一行都没改,因为我们的代码根本不依赖那个 SDK。这种“底层随便换,上层稳如山”的架构思想,比追任何一个具体的框架都值得投入。
6.4 对 Java 未来的一个实在判断
回到标题的问题:Java 还有希望吗?我的答案是,Java 在“把模型变成生产力”的这条路线上,希望很大。
大模型训练的牌桌确实坐满了 Python,但企业应用的大头根本不在这张牌桌上。Java 的十几年代码资产、Spring 生态、微服务治理能力、高性能和高稳定性积累,决定了它天然适合做 AI 能力的“最后一公里”:连接、编排、治理和交付。你可以看到,几乎所有云厂商最终都会提供 Java 语言的 SDK,因为客户的生产系统跑在 Java 上,这是绕不开的现实。
所以我不焦虑。Spring AI Alibaba 停更,我会说一声“知道了,换个方案继续”,但不会说“Java 完了”。真正决定你有没有希望的,从来不是某一个框架是否活跃,而是你能不能把纷繁复杂的技术变化,收敛到稳定的抽象层里。这既是我这次事件最大的收获,也是我建议每个 Java 开发者认真思考的一课。