欢迎光临
我们一直在努力

保姆级|Spring AI 2.0 第一个 Demo:Spring Boot 4 接入大模型(含国内可用方案 + 完整 pom)

保姆级|Spring AI 2.0 第一个 Demo:Spring Boot 4 接入大模型(含国内可用方案 + 完整 pom)

本文将解决:5 分钟内,用 Spring AI 2.0 的 ChatClient 把第一个大模型回答打印到控制台,并给出 OpenAI / DeepSeek / 通义 / Ollama 四种国内可用接入方案。

你将学到:

  • 为什么 Java 接入大模型首选 Spring AI,而不是手搓 HTTP
  • Spring AI 2.0 的依赖坐标与版本管理(spring-ai-bom)
  • 最小 application.yml 配置(base-url / api-key)
  • 两行代码完成第一次 ChatClient.call()
  • 三种国内可用方案:OpenAI 兼容协议接 DeepSeek/通义、本地 Ollama 零成本
  • 5 个新手必踩的坑(base-url、代理、超时、Key、版本冲突)

一、为什么 Java 接入大模型要选 Spring AI

很多 Java 开发者第一次接大模型,会用 RestTemplate / WebClient 手搓 OpenAI 的 HTTP 接口:自己拼 JSON、自己解析响应、自己处理流式 SSE。能跑,但很快会撞墙:换模型要重写、流式输出要自己管背压、工具调用要自己实现多轮循环、RAG 要自己接向量库。

Spring AI 的价值,就是把这套东西变成 Spring 生态里的原生抽象:像用 JdbcTemplate 一样用 ChatClient,像换数据库一样换模型。它由 Spring 官方团队维护,2.0 已经是生产可用的 GA 版本。

一句话定位:Spring AI 是 Spring 官方对"Java 调用大模型"这件事的标准化封装,不是又一个通用 Agent 框架,也不和 LangChain4j 抢同一个生态位——它深度融入 Spring Boot 的自动装配、可观测、依赖管理。


二、版本标注(重要,先看清楚)

本文基于以下版本,2.0 相对 1.x 有 breaking 变化,不要照抄 1.x 的老教程:

组件版本说明
Spring AI 2.0.1 BOM 统一锁版本
Spring Boot 4.1.x 2.0 要求 Boot 4.0/4.1,不是 Boot 3
JDK 21+ 2.0 最低要求 JDK 21,不是 JDK 17

⚠️ 如果你还在用 Boot 3.x + JDK 17 + Spring AI 1.x,请看本系列第 4 篇《1.x→2.0 迁移指南》。


三、环境准备

  • JDK 21(java -version 确认)
  • Maven 3.9+
  • 一个模型服务的 API Key(OpenAI 或 DeepSeek 任选,下文给出国内可用方案)

不需要 GPU、不需要装向量库、不需要任何额外中间件——入门就是这么轻。


四、依赖与完整 pom.xml

Spring AI 的版本管理靠 BOM(Bill of Materials):引入 spring-ai-bom 后,下面所有 spring-ai-starter-* 依赖都不用再写版本号,避免版本冲突。

创建 Maven 项目,pom.xml 如下(可直接复制):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<!– Spring Boot 4 父工程,统一依赖与插件版本 –>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>4.1.0</version>
<relativePath/>
</parent>

<groupId>com.example</groupId>
<artifactId>spring-ai-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-ai-demo</name>
<description>Spring AI 2.0 第一个 Demo</description>

<properties>
<java.version>21</java.version>
<spring-ai.version>2.0.1</spring-ai.version>
</properties>

<!– 关键:spring-ai-bom 统一锁 Spring AI 所有模块版本 –>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<!– Web 依赖:让 AI 通过 HTTP 接口对外提供服务 –>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!– OpenAI 模型 starter(版本由 BOM 管理) –>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

两个关键点:

  • spring-ai-bom 放在 dependencyManagement 里,spring-ai-starter-model-openai 不写版本号。
  • starter 命名是 spring-ai-starter-model-openai——不是老教程里的 spring-ai-openai-spring-boot-starter(那是 1.0 之前的旧名,2.0 已废弃,写了会报依赖找不到)。

  • 五、最小 application.yml 配置

    src/main/resources/application.yml:

    spring:
    ai:
    openai:
    api-key: ${OPENAI_API_KEY} # 从环境变量读取,别把 Key 硬编码进代码
    base-url: https://api.openai.com # 默认就是它,接国产模型时改成对应地址
    chat:
    options:
    model: gpt–4o–mini # 模型名;换成你的模型即可
    temperature: 0.7

    说明:2.0 对配置属性做了扁平化调整,chat.options.* 这层在部分 2.0.x 版本里已改名。本文代码尽量把 model/temperature 放到 Java 侧的 ChatOptions.builder() 里,从根上规避属性名漂移,配置里只留最稳的 api-key 和 base-url。这也是工程上的推荐做法——参数跟代码走,配置跟环境走。


    六、第一次调用:两行代码跑通

    最直接的跑通方式:写一个 CommandLineRunner,应用启动时打印一次 AI 回复,不用开浏览器、不用写 Controller。

    import org.springframework.ai.chat.client.ChatClient;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.Bean;

    @SpringBootApplication
    public class SpringAiDemoApplication {

    public static void main(String[] args) {
    SpringApplication.run(SpringAiDemoApplication.class, args);
    }

    @Bean
    CommandLineRunner runner(ChatClient.Builder builder) {
    return args -> {
    ChatClient chatClient = builder.build();
    String reply = chatClient.prompt()
    .user("用一句话介绍 Spring AI")
    .call()
    .content();
    System.out.println("AI 回复:" + reply);
    };
    }
    }

    启动应用(mvn spring-boot:run),控制台会打印出 AI 回复。到此你已经跑通了 Spring AI 2.0。

    核心就一个链式调用:builder.build() 拿到 ChatClient,.prompt().user("…").call().content() 发起请求并取回字符串。


    七、进阶:暴露成 HTTP 接口

    实际项目里 AI 能力要通过接口对外提供,加一个 Controller:

    import org.springframework.ai.chat.client.ChatClient;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;

    @RestController
    public class ChatController {

    private final ChatClient chatClient;

    // 直接注入 ChatClient.Builder,由框架装配
    public ChatController(ChatClient.Builder builder) {
    this.chatClient = builder.build();
    }

    @GetMapping("/chat")
    public String chat(@RequestParam(defaultValue = "你好,介绍一下你自己") String q) {
    return chatClient.prompt()
    .user(q)
    .call()
    .content();
    }
    }

    启动后访问:http://localhost:8080/chat?q=写一首关于Java的诗,即可得到回复。


    八、国内可用方案(三种)

    OpenAI 的 Key 很多人没有,这里给出三种国内可用的替代方案。

    方案 A:DeepSeek(OpenAI 兼容协议,改 base-url 即可)

    DeepSeek 提供了 OpenAI 兼容接口,不用换 starter,只改配置:

    spring:
    ai:
    openai:
    api-key: ${DEEPSEEK_API_KEY}
    base-url: https://api.deepseek.com # 也可写 https://api.deepseek.com/v1
    chat:
    options:
    model: deepseek–chat # DeepSeek 的对话模型

    代码完全不用改——这就是 Spring AI 抽象的价值(第 3 篇会展开讲)。

    方案 B:通义千问(阿里云,走兼容协议)

    阿里云百炼的 DashScope 也提供 OpenAI 兼容端点:

    spring:
    ai:
    openai:
    api-key: ${DASHSCOPE_API_KEY}
    base-url: https://dashscope.aliyuncs.com/compatible–mode/v1
    chat:
    options:
    model: qwen–plus

    方案 C:本地 Ollama(零成本、零 Key、数据不出本地)

    Ollama 让你在本地跑开源模型,完全免费、无需 Key、数据私有。先装 Ollama 并拉一个模型:

    # 安装后拉取一个模型(以 Qwen2.5 为例)
    ollama pull qwen2.5

    然后换 starter 和配置:

    <dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-ollama</artifactId>
    </dependency>

    spring:
    ai:
    ollama:
    base-url: http://localhost:11434 # Ollama 默认本地端口
    chat:
    options:
    model: qwen2.5 # 必须是已 ollama pull 的模型名

    三种方案对比:

    方案starterbase-url成本需要 Key适用
    OpenAI spring-ai-starter-model-openai https://api.openai.com 按量付费 是 效果最强
    DeepSeek spring-ai-starter-model-openai https://api.deepseek.com 便宜 是 性价比高
    通义千问 spring-ai-starter-model-openai https://dashscope.aliyuncs.com/compatible-mode/v1 按量 是 国内合规
    Ollama spring-ai-starter-model-ollama http://localhost:11434 免费 否 本地/私有化

    九、原理图解:一次调用的完整链路

    OpenAI/DeepSeek/OllamaChatModelChatClientChatController浏览器/控制台OpenAI/DeepSeek/OllamaChatModelChatClientChatController浏览器/控制台#mermaid-svg-Kn4A7222KfLh6EII{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Kn4A7222KfLh6EII .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Kn4A7222KfLh6EII .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Kn4A7222KfLh6EII .error-icon{fill:#552222;}#mermaid-svg-Kn4A7222KfLh6EII .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Kn4A7222KfLh6EII .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Kn4A7222KfLh6EII .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Kn4A7222KfLh6EII .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Kn4A7222KfLh6EII .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Kn4A7222KfLh6EII .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Kn4A7222KfLh6EII .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Kn4A7222KfLh6EII .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Kn4A7222KfLh6EII .marker.cross{stroke:#333333;}#mermaid-svg-Kn4A7222KfLh6EII svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Kn4A7222KfLh6EII p{margin:0;}#mermaid-svg-Kn4A7222KfLh6EII .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-Kn4A7222KfLh6EII text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-Kn4A7222KfLh6EII .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-Kn4A7222KfLh6EII .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-Kn4A7222KfLh6EII .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-Kn4A7222KfLh6EII .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-Kn4A7222KfLh6EII #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-Kn4A7222KfLh6EII .sequenceNumber{fill:white;}#mermaid-svg-Kn4A7222KfLh6EII #sequencenumber{fill:#333;}#mermaid-svg-Kn4A7222KfLh6EII #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-Kn4A7222KfLh6EII .messageText{fill:#333;stroke:none;}#mermaid-svg-Kn4A7222KfLh6EII .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-Kn4A7222KfLh6EII .labelText,#mermaid-svg-Kn4A7222KfLh6EII .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-Kn4A7222KfLh6EII .loopText,#mermaid-svg-Kn4A7222KfLh6EII .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-Kn4A7222KfLh6EII .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-Kn4A7222KfLh6EII .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-Kn4A7222KfLh6EII .noteText,#mermaid-svg-Kn4A7222KfLh6EII .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-Kn4A7222KfLh6EII .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-Kn4A7222KfLh6EII .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-Kn4A7222KfLh6EII .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-Kn4A7222KfLh6EII .actorPopupMenu{position:absolute;}#mermaid-svg-Kn4A7222KfLh6EII .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-Kn4A7222KfLh6EII .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-Kn4A7222KfLh6EII .actor-man circle,#mermaid-svg-Kn4A7222KfLh6EII line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-Kn4A7222KfLh6EII :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}GET /chat?q=你好prompt().user(q).call()组装 Prompt(含角色/参数)HTTP 请求(携带 api-key)模型生成的回复ChatResponsecontent() 取字符串返回回复

    要点:你的业务代码只和 ChatClient 打交道,ChatClient 背后是 ChatModel,ChatModel 再去调真正的模型服务。换模型(DeepSeek/通义/Ollama)只是换 ChatModel 的实现,业务代码零改动。


    十、踩坑 FAQ(新手必看,都是真实报错)

    坑 1:启动报 NoSuchMethodError / 类找不到

    现象:一启动就报 java.lang.NoSuchMethodError 或 ClassNotFoundException。
    原因:忘了引入 spring-ai-bom,导致各 starter 版本互相冲突;或把 starter 写成了旧名 spring-ai-openai-spring-boot-starter。
    解决:确认 pom.xml 里有 dependencyManagement 引入 spring-ai-bom,starter 用 spring-ai-starter-model-openai。

    坑 2:报 apiKey must not be null

    现象:启动或调用时抛异常,提示 api key 为空。
    原因:api-key 没配,或环境变量 OPENAI_API_KEY 没设。
    解决:确认 application.yml 里 api-key: ${OPENAI_API_KEY},并在启动前 export OPENAI_API_KEY=sk-xxx。

    坑 3:请求返回 404

    现象:能启动,但调用模型报 404。
    原因:base-url 写错了路径——常见是少了 /v1 或多写了一段。
    解决:核对 base-url。DeepSeek 用 https://api.deepseek.com(或其 /v1);通义兼容端点必须带 /compatible-mode/v1。

    坑 4:Connection refused 或 Read timed out

    现象:连接被拒或读超时。
    原因:公司/校园网络有代理拦截;或 Ollama 没启动。
    解决:走代理时给 JVM 加代理参数 -Dhttp.proxyHost=… -Dhttp.proxyPort=…;用 Ollama 前先 ollama serve 确保服务在 11434 端口。

    坑 5:Boot 3 上跑 Spring AI 2.0 起不来

    现象:把 spring-ai 版本改成 2.0,但 Boot 还是 3.x,启动报兼容错。
    原因:Spring AI 2.0 只支持 Boot 4.0/4.1,和 Boot 3 不兼容。
    解决:要么 Boot 升到 4.1,要么 Spring AI 降到 1.1.x。两者版本必须匹配(详见第 4 篇迁移指南)。


    十一、小结与合集导航

    这一篇你完成了 Spring AI 2.0 的"从 0 到 1":BOM 版本管理、最小配置、ChatClient 首次调用、三种国内可用方案、五个新手坑。

    下一步建议按顺序读:

    • 下一篇:《ChatClient Fluent API 全拆解》——把 .prompt()/call()/stream() 和消息角色、参数调优彻底讲透
    • 收藏备用:本合集「Spring AI 深入浅出」总目录(文末置顶评论有链接)
    • 源码仓库:本篇完整可运行代码见文末置顶评论的 GitHub 仓库

    十二、互动钩子

    投票:你准备用哪个模型接入?

    • OpenAI
    • DeepSeek
    • 通义千问
    • 本地 Ollama
    • 其他

    评论区晒出你的第一个跑通截图,我会逐条答疑;源码与合集导航已置顶评论,欢迎自取。

    赞(0)
    未经允许不得转载:171主机测评 » 保姆级|Spring AI 2.0 第一个 Demo:Spring Boot 4 接入大模型(含国内可用方案 + 完整 pom)
    分享到: 更多 (0)

    评论 抢沙发

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