不知不觉已经2个多月,感谢各位朋友的认可和支持!
随着AI的日新月异,很多公司都开展了AI相关的业务,这也使得很多公司的老板都想去沾沾边,而他却不知道自己公司的项目即屎山代码还是老的架构,所以很多朋友问:"老项目呢?大量Spring 4/Spring Boot 1.x的核心系统,想做AI但新框架都用不了,升级风险又大" 这个问题问得太真实了。不少公司的核心系统还跑在Spring Framework 4.x / Spring Boot 1.x上,想做大模型功能,但一查文档就懵了------Spring AI要求Spring Boot 3.x,LangChain4j的Spring Boot集成也要2.7起步,直接引入全是javax.*和jakarta.*的冲突,编译都过不了。 这个问题问得太真实了。很多公司的核心系统还跑在Spring Framework 4.x / Spring Boot 1.x上,想做大模型功能,但一查文档就懵了------Spring AI要求Spring Boot 3.x,LangChain4j的Spring Boot集成也要2.7起步,直接引入全是javax.*和jakarta.*的冲突,编译都过不了。
升级框架?那可是核心业务系统,回归测试跑一遍半个月,出了事故谁背锅?
但Spring 4就真的没法做AI了吗?当然不是。 大模型本质上就是个HTTP接口,和你调第三方支付、调短信网关没有任何区别。今天给3种方案,从最简单的零依赖手写调用,到官方SDK,再到微服务拆分,不用升级一行Spring代码,Spring 4项目也能接入大模型。
先搞清楚:为什么新框架在Spring 4里用不了?
很多人以为是版本太低,其实核心原因是Java EE和Jakarta EE的不兼容。
- Spring 4 / Spring Boot 1.x → 用的是 Java EE ,包名是
javax.servlet.*、javax.persistence.* - Spring Boot 3.x / Spring 6 → 用的是 Jakarta EE ,包名是
jakarta.servlet.*、jakarta.persistence.*
这两个包名不兼容,所以Spring AI、LangChain4j的Spring Boot Starter这些基于Spring Boot 3的框架,直接在Spring 4项目里引入就会报类冲突。但注意:不兼容的是"Spring集成层",不是"大模型调用本身"。 只要不用那些Spring Boot Starter,纯Java的大模型调用在任何Spring版本里都能跑。
理解了这一点,下面3种方案就顺理成章了。
方案1:OkHttp手写调用大模型API(零依赖,首选)
这是最简单、最通用、最不容易出问题的方案。大模型的接口就是标准的HTTP POST,返回JSON,你用OkHttp发请求、用fastjson解析响应,完事。
优点 :零Spring依赖,JDK 6+就能跑,不侵入现有项目,不会有任何依赖冲突 缺点:需要自己封装重试、超时、流式输出(但这些都不难)
第一步:引入依赖(Spring 4兼容版本)
注意版本选择,不要用最新版,最新版可能要求高版本JDK:
xml
<!-- OkHttp 3.12.x是最后一个支持JDK 7的版本,JDK 8用3.14.x也没问题 -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.14.9</version>
</dependency>
<!-- fastjson 1.2.x,兼容低版本JDK,不要用fastjson2 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
第二步:封装大模型客户端
java
package com.example.ai;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* 大模型通用客户端(Spring 4兼容,零Spring依赖)
* 基于通义千问OpenAI兼容接口,其他模型改base-url即可
*/
public class LlmClient {
private final OkHttpClient httpClient;
private final String apiKey;
private final String baseUrl;
private final String model;
public LlmClient(String apiKey, String baseUrl, String model) {
this.apiKey = apiKey;
this.baseUrl = baseUrl;
this.model = model;
this.httpClient = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build();
}
/**
* 最简对话调用
* @param systemPrompt 系统提示词
* @param userMessage 用户问题
* @return 大模型回答
*/
public String chat(String systemPrompt, String userMessage) throws IOException {
// 1. 构建消息
JSONObject systemMsg = new JSONObject();
systemMsg.put("role", "system");
systemMsg.put("content", systemPrompt);
JSONObject userMsg = new JSONObject();
userMsg.put("role", "user");
userMsg.put("content", userMessage);
JSONArray messages = new JSONArray();
messages.addAll(Arrays.asList(systemMsg, userMsg));
// 2. 构建请求体
JSONObject requestBody = new JSONObject();
requestBody.put("model", model);
requestBody.put("messages", messages);
requestBody.put("temperature", 0.3);
// 3. 发送HTTP请求
Request request = new Request.Builder()
.url(baseUrl + "/chat/completions")
.addHeader("Authorization", "Bearer " + apiKey)
.addHeader("Content-Type", "application/json")
.post(RequestBody.create(
MediaType.parse("application/json; charset=utf-8"),
requestBody.toJSONString()))
.build();
// 4. 解析响应
try (Response response = httpClient.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException("大模型调用失败,HTTP状态码:" + response.code()
+ ",响应:" + response.body().string());
}
String body = response.body().string();
JSONObject json = JSON.parseObject(body);
return json.getJSONArray("choices")
.getJSONObject(0)
.getJSONObject("message")
.getString("content");
}
}
/**
* 带重试的调用(生产环境必备)
*/
public String chatWithRetry(String systemPrompt, String userMessage, int maxRetries) {
for (int i = 0; i < maxRetries; i++) {
try {
return chat(systemPrompt, userMessage);
} catch (IOException e) {
System.err.println("第" + (i + 1) + "次调用失败:" + e.getMessage());
if (i == maxRetries - 1) {
throw new RuntimeException("大模型调用失败,已重试" + maxRetries + "次", e);
}
try {
Thread.sleep(1000 * (i + 1)); // 指数退避
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
}
}
return null;
}
}
第三步:在Spring 4项目里使用
kotlin
package com.example.service;
import com.example.ai.LlmClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.io.IOException;
/**
* 在Spring 4项目中使用大模型
* 注意:这里用的是javax.annotation.PostConstruct(Java EE),
* 不是jakarta.annotation.PostConstruct(Jakarta EE)
*/
@Service
public class AiService {
@Value("${llm.api-key}")
private String apiKey;
@Value("${llm.base-url:[https://dashscope.aliyuncs.com/compatible-mode/v1](https://dashscope.aliyuncs.com/compatible-mode/v1)}")
private String baseUrl;
@Value("${llm.model:qwen-turbo}")
private String model;
private LlmClient llmClient;
@PostConstruct
public void init() {
// 手动new出来,不需要Spring Boot Starter自动装配
this.llmClient = new LlmClient(apiKey, baseUrl, model);
}
/**
* 智能问答
*/
public String ask(String question) {
try {
String systemPrompt = "你是一个 helpful 的智能助手,回答要简洁准确。";
return llmClient.chatWithRetry(systemPrompt, question, 3);
} catch (Exception e) {
// 降级兜底:大模型不可用时返回默认回答
return "抱歉,AI服务暂时不可用,请稍后重试。";
}
}
}
关键点:整个客户端没有任何Spring依赖,就是纯Java + OkHttp + fastjson。你把
LlmClient这个类复制到任何Spring 4、Spring 3、甚至纯Servlet项目里,都能直接用。这是最稳妥的方案,没有之一。
方案2:引入官方SDK,不依赖Spring版本
如果你不想自己封装HTTP调用,可以用大模型厂商的官方SDK。这些SDK通常是纯Java库,不依赖Spring,所以在Spring 4项目里也能直接引入。
以阿里通义千问的官方SDK为例:
第一步:引入依赖
xml
<!-- 通义千问官方SDK,纯Java库,不依赖Spring -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dashscope-sdk-java</artifactId>
<version>2.14.6</version> <!-- 选兼容JDK 8的版本,不要用最新版 -->
</dependency>
第二步:使用SDK调用
java
package com.example.ai;
import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import java.util.Arrays;
/**
* 使用官方SDK调用大模型(不依赖Spring)
*/
public class DashScopeService {
private final String apiKey;
public DashScopeService(String apiKey) {
this.apiKey = apiKey;
}
public String chat(String userMessage) throws Exception {
// 1. 构建消息
Message systemMsg = Message.builder()
.role(Role.SYSTEM.getValue())
.content("你是一个 helpful 的助手。")
.build();
Message userMsg = Message.builder()
.role(Role.USER.getValue())
.content(userMessage)
.build();
// 2. 构建请求参数
GenerationParam param = GenerationParam.builder()
.apiKey(apiKey)
.model("qwen-turbo")
.messages(Arrays.asList(systemMsg, userMsg))
.temperature(0.3f)
.build();
// 3. 调用
Generation gen = new Generation();
GenerationResult result = gen.call(param);
// 4. 解析结果
return result.getOutput().getChoices().get(0).getMessage().getContent();
}
}
优点 :官方维护,功能全(支持流式、Function Calling、多模态等),不用自己封装HTTP 缺点:
- 引入额外依赖,老项目可能和现有依赖冲突(比如okhttp版本、gson版本)
- SDK版本更新快,新版本可能要求高版本JDK,一定要选兼容你JDK版本的旧版本
- 绑定特定厂商,换大模型要改代码
避坑提醒:引入官方SDK前,先看它的依赖树。很多SDK内部依赖了okhttp、gson、guava等,如果你的项目里已经有这些库且版本不同,很容易出现
NoSuchMethodError。冲突了就用maven的exclusions排掉,或者干脆回方案1自己手写。
方案3:单独起AI微服务,老项目HTTP/RPC调用(长期推荐)
如果你的AI功能会越来越复杂(要做RAG、Agent、多轮对话、流式输出),方案1和2就不够用了------你会想要Spring AI、LangChain4j这些完整框架的能力,但又不想动老项目。
这时候最佳方案是:新起一个独立的AI微服务,用最新的Spring Boot 3 + LangChain4j,老项目通过HTTP或RPC调用它。
架构图
javascript
┌─────────────────────┐ HTTP/Feign ┌─────────────────────┐
│ 老项目(Spring 4)│ ───────────────────> │ AI微服务(Spring Boot 3)│
│ 业务逻辑/数据库 │ │ LangChain4j / RAG / Agent │
│ 现有功能不变 │ <─────────────────── │ 大模型调用 / 向量检索 │
└─────────────────────┘ JSON响应 └─────────────────────┘
老项目侧调用代码(Feign,Spring 4兼容)
typescript
package com.example.ai;
import feign.Headers;
import feign.Param;
import feign.RequestLine;
/**
* Feign客户端调用AI微服务(Spring 4兼容,用feign-core即可)
*/
public interface AiServiceClient {
@RequestLine("POST /api/ai/chat")
@Headers("Content-Type: application/json")
String chat(ChatRequest request);
class ChatRequest {
private String question;
private String userId;
// getter/setter省略
public String getQuestion() { return question; }
public void setQuestion(String question) { this.question = question; }
public String getUserId() { return userId; }
public void setUserId(String userId) { this.userId = userId; }
}
}
kotlin
// 在Spring 4项目中配置Feign客户端
package com.example.config;
import com.example.ai.AiServiceClient;
import feign.Feign;
import feign.jackson.JacksonDecoder;
import feign.jackson.JacksonEncoder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AiServiceConfig {
@Value("${ai.service.url:[http://localhost:8081](http://localhost:8081)}")
private String aiServiceUrl;
@Bean
public AiServiceClient aiServiceClient() {
return Feign.builder()
.encoder(new JacksonEncoder())
.decoder(new JacksonDecoder())
.target(AiServiceClient.class, aiServiceUrl);
}
}
优点:
- AI能力独立演进,新技术随便用(Spring Boot 3、LangChain4j、流式输出、RAG全上)
- 不影响老项目,老项目代码几乎不用改
- 独立部署、独立扩容、独立监控,AI服务挂了不影响核心业务
- 多个老项目可以共用一个AI微服务
缺点:
- 多一个服务要运维(但现在容器化部署很简单)
- 有网络开销(内网调用延迟很低,可忽略)
- 需要处理服务发现、鉴权等微服务基础问题
核心判断:如果只是简单调大模型问答,方案1就够了;如果AI功能会持续迭代、越来越复杂,直接上方案3,一劳永逸。
三种方案对比
| 维度 | 方案1:OkHttp手写 | 方案2:官方SDK | 方案3:微服务拆分 |
|---|---|---|---|
| 依赖侵入性 | 极低(仅OkHttp+fastjson) | 中(SDK+传递依赖) | 老项目零侵入 |
| 改造成本 | 最低(复制一个类) | 低(引入依赖+调用) | 中(新起服务+接口对接) |
| 功能完整度 | 基础(需自己扩展) | 高(官方全功能) | 最高(任何框架都能用) |
| 维护成本 | 低(自己控制代码) | 中(跟SDK版本升级) | 中(多一个服务) |
| 依赖冲突风险 | 几乎为零 | 有(需排查传递依赖) | 零 |
| 适用场景 | 简单问答、快速接入 | 需要官方高级功能 | AI功能复杂、长期迭代 |
我的选型建议
- 你只是想给老项目加个智能问答/文案生成功能? → 方案1,OkHttp手写,半小时搞定,最稳妥
- 你需要流式输出、Function Calling等高级功能,又不想起新服务? → 方案2,官方SDK,注意选兼容版本
- 你要做完整的RAG/Agent系统,AI功能会持续迭代? → 方案3,微服务拆分,长期来看最省心
- 你的项目JDK版本特别低(JDK 6/7)? → 方案1,选OkHttp 3.12.x + fastjson 1.2.x,这是唯一能跑的方案
最后说一句:不要被"新框架必须高版本Spring"吓住。 大模型的本质就是HTTP接口,只要能发HTTP请求,任何Java项目都能做AI。先从方案1跑通最小闭环,看到效果再决定要不要升级,这才是老项目做AI的正确姿势。
📦 落地资源推荐
AI应用框架开发需要稳定的测试环境,我平时调试框架、跑RAG验证都用阿里云轻量应用服务器,2核4G跑SpringBoot + 大模型调用完全够用,新用户首年特惠性价比很高再加上现在可以领取的9折券,适合自己动手搭一个AI测试环境。有部署需求的朋友,可以点击查看www.aliyun.com/daily-act/e...
💡 领取完整源码

关注图片上水印即Java-AI工程师,后台回复【选型】,领取本文完整源码,含 OkHttp 手写客户端(带重试降级)、DashScope SDK 调用示例、Feign 微服务调用示例、Spring 4 兼容版本 pom.xml,复制到项目直接运行。
📢 下期预告
选型踩坑是Java开发者的普遍痛点,很多人为了技术而技术,盲目上框架,最后发现不匹配,重构成本极高。所以我们下一篇讲:Java AI 框架选型最容易踩的 5 个坑:90% 的人至少中 2 个 本文属于「Java AI工具选型」合集