Day26-Java核心+Spring生态篇:5行代码接入大模型Spring AI
一、Spring AI 是什么Spring AI 是 Spring 官方推出的AI应用开发框架核心做了三件事统一抽象层把OpenAI、通义千问、DeepSeek、Ollama等不同模型提供商的API差异屏蔽掉你换模型只改配置不改代码。工程化封装Prompt模板、结构化输出、Function Calling、RAG、向量存储……这些AI开发的高频需求全部有开箱即用的API。Spring原生集成自动配置、依赖注入、Actuator监控跟你写了十年的Spring Boot应用无缝融合。用一张图理解Spring AI的核心架构关键洞察这跟当年Spring Data JPA统一各种数据库的操作是一模一样的思路。Spring最擅长的事情就是——在混乱的API之上建立统一的抽象。二、项目初始化3分钟跑起来2.1 创建项目使用 Spring Initializrhttps://start.spring.io创建项目选择以下依赖Spring Boot 3.3.x最低要求3.2Spring WebSpring AI DashScope Starter通义千问或Spring AI OpenAI Starter如果你用Maven手动创建核心POM配置如下!-- 父POM锁定Spring Boot版本 -- parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.3.5/version relativePath/ /parent properties java.version17/java.version !-- Spring AI版本截至2024年底稳定版 -- spring-ai.version1.0.0-M4/spring-ai.version /properties dependencies !-- Spring Boot Web -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !-- Spring AI BOM统一管理所有AI相关依赖版本 -- dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version${spring-ai.version}/version typepom/type scopeimport/scope /dependency !-- 接入通义千问DashScope -- dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-starter/artifactId version1.0.0-M3.2/version /dependency !-- 或者接入DeepSeek兼容OpenAI协议 -- dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-openai-spring-boot-starter/artifactId /dependency /dependencies !-- Spring AI的Milestone仓库必须加否则拉不到包 -- repositories repository idspring-milestones/id nameSpring Milestones/name urlhttps://repo.spring.io/milestone/url snapshotsenabledfalse/enabled/snapshots /repository /repositories2.2 配置API Key在application.yml中配置方式一接入通义千问DashScopespring: ai: dashscope: api-key: ${AI_DASHSCOPE_API_KEY} # 从环境变量读取别硬编码到代码里 chat: options: model: qwen-plus # 模型名称qwen-plus / qwen-turbo / qwen-max temperature: 0.7 # 温度0~1越高越发散方式二接入DeepSeek兼容OpenAI协议spring: ai: openai: api-key: ${AI_DEEPSEEK_API_KEY} base-url: https://api.deepseek.com # DeepSeek的API地址 chat: options: model: deepseek-chat # 或 deepseek-reasonerR1推理模型 temperature: 0.7为什么DeepSeek用OpenAI的starter因为DeepSeek的API完全兼容OpenAI协议只需要改base-url和api-key就行。这也是Spring AI统一抽象的威力——兼容OpenAI协议的模型统统用同一个starter。三、5行代码接入大模型ChatClient初体验3.1 最简版本RestController public class ChatController { private final ChatClient chatClient; // 构造器注入Spring AI自动配置已经帮你创建好了ChatClient.Builder public ChatController(ChatClient.Builder builder) { this.chatClient builder.build(); } GetMapping(/chat) public String chat(RequestParam String message) { return chatClient.prompt(message).call().content(); } }就这5行核心代码构造器注入 一行调用启动项目后访问http://localhost:8080/chat?message用一句话解释什么是依赖注入你会收到类似这样的回复依赖注入是一种设计模式对象不自己创建依赖项而是由外部容器将所需依赖注入进来从而实现松耦合。一个GET请求接入了大模型。这就是Spring AI的入门体验。3.2 理解调用链路别急着往下走我们先搞懂这行代码背后发生了什么chatClient.prompt(message) // 1. 构建Prompt .call() // 2. 发起同步HTTP请求到模型API .content(); // 3. 提取文本内容忽略token使用量等元数据完整链路是这样的你的代码 → ChatClient → ChatModel → 模型API通义千问/DeepSeek ↓ 返回 ChatResponse ↓ .content() 提取纯文本ChatClient是面向开发者的高级API类似Spring Data的RepositoryChatModel是底层模型接口。你日常开发90%的场景用ChatClient就够了。3.3 带系统提示词的对话实际业务中你通常需要设定AI的角色和行为规则。Spring AI用链式API优雅地处理这个GetMapping(/assistant) public String assistant(RequestParam String question) { return chatClient.prompt() // system消息设定AI角色和行为约束 .system(你是一个资深的Java技术顾问回答简洁专业 每次回答不超过200字代码示例用Java语言。) // user消息用户实际输入 .user(question) // 调用配置 .call() // 获取结构化结果包含内容、token用量等 .chatResponse() .getResult() .getOutput() .getContent(); }对比一下如果你自己拼接OpenAI的JSON请求体需要手动构造messages数组、区分system和user角色、解析返回的JSON……Spring AI把这些全封装了。3.4 多模型切换只改配置不改代码这是Spring AI最值钱的设计。你写好的ChatController代码切换模型只需要改配置# 开发环境用通义千问便宜 spring: ai: dashscope: api-key: ${AI_DASHSCOPE_API_KEY} chat: options: model: qwen-turbo # 生产环境切到DeepSeek性价比高 # spring: # ai: # openai: # api-key: ${AI_DEEPSEEK_API_KEY} # base-url: https://api.deepseek.com # chat: # options: # model: deepseek-chat当然如果你想在运行时动态切换模型比如简单问题用turbo、复杂问题用max可以通过注入多个ChatModel实现Service public class SmartChatService { private final ChatClient qwenClient; // 通义千问 private final ChatClient deepseekClient; // DeepSeek public SmartChatService( Qualifier(dashScopeChatModel) ChatModel qwenModel, Qualifier(openAiChatModel) ChatModel deepseekModel) { this.qwenClient ChatClient.builder(qwenModel).build(); this.deepseekClient ChatClient.builder(deepseekModel).build(); } public String chat(String question, String model) { ChatClient client deepseek.equalsIgnoreCase(model) ? deepseekClient : qwenClient; return client.prompt(question).call().content(); } }这种模型路由的思路在后面Day 89的综合项目里会详细展开这里先埋个种子。四、进阶结构化输出——让AI返回Java对象大模型默认返回的是自然语言文本但在工程中我们经常需要AI返回结构化数据比如JSON直接映射成Java对象。4.1 场景智能情感分析假设你有一个用户评论分析系统需要AI判断评论的情感倾向并返回结构化结果// 定义输出结构Java RecordJDK 16 public record SentimentResult( String sentiment, // POSITIVE / NEGATIVE / NEUTRAL double confidence, // 置信度 0~1 String summary // 一句话摘要 ) {} RestController public class SentimentController { private final ChatClient chatClient; public SentimentController(ChatClient.Builder builder) { this.chatClient builder.build(); } PostMapping(/analyze) public SentimentResult analyze(RequestBody MapString, String body) { String review body.get(review); return chatClient.prompt() .system(你是一个情感分析专家。分析用户评论的情感倾向 返回POSITIVE/NEGATIVE/NEUTRAL给出置信度和摘要。) .user(请分析以下评论\n review) .call() // 核心魔法entity()方法自动将AI输出转换为指定类型的Java对象 .entity(SentimentResult.class); } }调用示例curl -X POST http://localhost:8080/analyze \ -H Content-Type: application/json \ -d {review: 这个ERP系统太好用了库存管理清晰报表功能强大强烈推荐}返回结果{ sentiment: POSITIVE, confidence: 0.95, summary: 用户对ERP系统的库存管理和报表功能给予高度评价。 }原理entity()方法底层使用了BeanOutputConverter它做了三件事根据目标Java类型自动生成JSON Schema追加到Prompt中告诉模型输出格式调用模型获取文本响应将文本解析为JSON并反序列化为Java对象这意味着你不需要写任何JSON解析代码Spring AI帮你全搞定了。4.2 对比传统方案的痛点如果没有Spring AI你需要// 传统做法手动拼接 手动解析 String prompt 分析以下评论的情感返回JSON格式 {\sentiment\:\POSITIVE/NEGATIVE/NEUTRAL\, \confidence\:0.0,\summary\:\\}\n review; String response callLlmApi(prompt); // 自己封装HTTP调用 // 手动解析JSON还可能遇到模型不按格式返回的问题 ObjectMapper mapper new ObjectMapper(); SentimentResult result mapper.readValue(response, SentimentResult.class);痛点很明显Prompt和代码耦合、JSON格式不稳定、没有类型安全、换模型要改HTTP调用代码。Spring AI把这些问题全解决了。五、模型选型与成本对比很多开发者问我该选哪个模型我的建议是根据业务场景和预算来维度通义千问 (qwen-plus)DeepSeek (deepseek-chat)GPT-4o中文能力优秀优秀良好代码能力良好优秀性价比之王优秀输入价格¥0.008/1K tokens¥0.001/1K tokens¥0.035/1K tokens输出价格¥0.02/1K tokens¥0.002/1K tokens¥0.07/1K tokens免费额度有新用户有限时无上下文窗口128K128K128K合规性国内合规国内合规需评估价格数据为2024年底公开价格实际以官方为准。我的选型建议内部工具/原型验证DeepSeek便宜到几乎不花钱面向用户的中文场景通义千问中文表达自然复杂代码推理DeepSeek-R1推理模型或GPT-4o数据敏感场景后面Day 61会讲Ollama本地部署六、建议建议1API Key永远不要硬编码// ❌ 错误硬编码到代码里一旦提交到Git就完蛋 Value(${spring.ai.dashscope.api-key}) private String apiKey sk-xxxxxxx; // ✅ 正确用环境变量注入 // application.yml中写 ${AI_DASHSCOPE_API_KEY} // 启动时export AI_DASHSCOPE_API_KEYsk-xxxxxxx更进一步生产环境用Nacos配置中心或Vault管理密钥不要放在代码仓库里。建议2永远设置超时和重试大模型API的延迟远高于传统接口通常2~10秒不设超时会拖垮你的线程池yaml复制spring: ai: dashscope: chat: options: model: qwen-plus # Spring AI的retry配置M4版本支持 retry: max-attempts: 3 # 最多重试3次 backoff: initial-interval: 1000 # 首次重试等待1秒 multiplier: 2 # 指数退避1s → 2s → 4s同时你的HTTP客户端Tomcat/Undertow也要确保超时时间大于模型的最大响应时间server: tomcat: connection-timeout: 30000 # 30秒超时 threads: max: 200 # 根据并发量调整建议3从简单场景开始不要一上来就RAG我见过太多团队一上来就搞RAG知识库结果文档切分、向量检索、重排序一堆问题项目延期两个月。正确的节奏是第一步ChatClient跑通基础对话今天这篇 ↓ 第二步Prompt工程让AI按你的规则输出Day 27 ↓ 第三步结构化输出 Function Calling让AI调你的业务接口 ↓ 第四步RAG给AI喂你的私有知识Day 71每一步都要确保上一步能稳定运行。AI应用开发的坑不在框架而在调优和边界处理。下篇预告Day 27 —— 《Spring AI Prompt工程PromptTemplate/FewShot/角色系统》我们将深入Prompt模板化管理把调教AI这件事工程化、可版本管理地做起来。

相关新闻

Claude Code v2.1.211安装配置与AI编程助手实战指南

Claude Code v2.1.211安装配置与AI编程助手实战指南

最近在开发过程中,很多同学反馈希望找到一款既能提供智能代码补全,又能进行深度代码分析的AI编程助手。Claude Code作为Anthropic推出的专业代码生成工具,在v2.1.211版本中带来了多项实用改进,特别是对中文开发环境的优化支持。本…

2026/10/12 10:07:37 阅读更多 →
Android Studio中文语言包:5分钟打造完美中文开发环境

Android Studio中文语言包:5分钟打造完美中文开发环境

Android Studio中文语言包:5分钟打造完美中文开发环境 【免费下载链接】AndroidStudioChineseLanguagePack AndroidStudio中文插件(官方修改版本) 项目地址: https://gitcode.com/gh_mirrors/an/AndroidStudioChineseLanguagePack 你是否曾经面对…

2026/10/11 0:38:41 阅读更多 →
终极窗口强制调整工具:3分钟掌握WindowResizer任意修改窗口尺寸

终极窗口强制调整工具:3分钟掌握WindowResizer任意修改窗口尺寸

终极窗口强制调整工具:3分钟掌握WindowResizer任意修改窗口尺寸 【免费下载链接】WindowResizer 一个可以强制调整应用程序窗口大小的工具 项目地址: https://gitcode.com/gh_mirrors/wi/WindowResizer 还在为那些顽固不化的Windows窗口而烦恼吗?…

2026/10/6 16:30:58 阅读更多 →

最新新闻

C++字符类型char与wchar_t深度解析

C++字符类型char与wchar_t深度解析

1. 理解C中的字符类型本质在C开发中,字符处理是每个程序员都会遇到的基础问题。char和wchar_t看似简单,但背后涉及字符编码、国际化支持等复杂概念。我们先从内存层面理解它们的物理差异:char类型保证至少8位宽度,这源于C语言的遗…

2026/10/14 11:01:09 阅读更多 →
LangGraph工具调用与菜单RAG:语音助手菜单查询落地实践

LangGraph工具调用与菜单RAG:语音助手菜单查询落地实践

语音助手的对话流里,用户说“帮我查一下附近有哪些川菜馆”,系统到底是怎么把“川菜馆”这个模糊的口语表达,变成一次数据库查询,再把查询结果组织成一句像样的人话返回去的?前面几篇我们聊了LangGraph的状态管理和多轮…

2026/10/14 11:01:09 阅读更多 →
第十一届蓝桥杯B组C/C++省赛全题解:从填空到DP的完整思路

第十一届蓝桥杯B组C/C++省赛全题解:从填空到DP的完整思路

参加过第11届蓝桥杯B组省赛的老选手应该都有同感:这届比赛原本定在4月份,因为疫情硬是拖到了7月,原本的线下笔试改成线上双机位监考。很多人的复习节奏完全被打乱,刷题计划和心态都受影响。但拿题目本身来说,B组的C/C卷…

2026/10/14 11:01:09 阅读更多 →
Data+AI一体化平台实战:智能目录、增强开发与MLOps落地指南

Data+AI一体化平台实战:智能目录、增强开发与MLOps落地指南

原生标题太长也太营销化了,我帮你提炼成真实博主口吻的硬核标题,再按规范生成一篇完全去平台化的深度博文。以下是正文直接输出。1. 不只是提效工具:一体化数据智能平台到底解决什么问题先说结论再展开。我们团队真实数据栈曾经是典型的三层饺…

2026/10/14 11:01:09 阅读更多 →
StarModAPI 在 StarMade 服务器中的实现:加载器接入、事件注册与性能优化

StarModAPI 在 StarMade 服务器中的实现:加载器接入、事件注册与性能优化

简介:StarMod 是一份面向 Java 服务端开发者的开源项目源码,基于 StarModAPI 为沙盒太空模拟游戏《StarMade》提供可扩展、可定制的服务器实现,适合希望深入理解游戏服务器架构、网络通信与插件机制的中高级开发者研读。压缩包共 66 个文件&a…

2026/10/14 11:01:09 阅读更多 →
自研可逆字符串长度压缩算法:设计思路与工程实现

自研可逆字符串长度压缩算法:设计思路与工程实现

做这个项目的起因其实挺有意思。有一次我在处理一批数据库导出的文本字段,中间层要求把每条记录的长度压到某个阈值以下,但又不能让数据丢失,因为下游还要做精确校验。当时我翻遍了现成的压缩库,要么是有损的哈希方案,…

2026/10/14 11:00:07 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →