
Spring AI这个框架最近热度一直居高不下。但很多人第一步就卡住了明明照着官方文档敲了依赖IDEA里却一片爆红Maven下载依赖要么慢如蜗牛要么直接失败。更头疼的是Spring AI本身的版本迭代极快网上搜到的教程不少但很多依赖坐标已经过时照着抄都抄不对。这篇文章就是写给那些准备入手Spring AI、却在Maven依赖阶段就被劝退的朋友。我会从Maven的基本职责讲起到仓库配置、依赖坐标选择、常见报错排查最后聊到Spring AI连接本地DeepSeek这类实际场景。全程基于我实际踩坑的经验不整虚的全是能直接落地的东西。1. 为什么Spring AI开发第一步是搞定Maven而不是写代码很多新手有个误区学一个新框架第一件事应该是找Demo、写代码。但Spring AI这种快速迭代的框架恰恰相反第一道门槛是依赖管理。1.1 Maven在Spring AI项目里到底扮演什么角色Maven本质上是一个项目构建和依赖管理工具。你可以把它理解成一个自动化的快递中转站你在pom.xml里声明需要哪些库Maven就去中央仓库把对应的jar包拉下来然后帮你把项目打包成可运行的形态。Spring AI的代码结构非常依赖Maven的这种能力。官方文档会告诉你引入spring-ai-openai-spring-boot-starter或spring-ai-alibaba之类的依赖但这些依赖背后还有一大串传递依赖。比如你引入Spring AI的OpenAI模块它会自动带上Spring Boot、Spring Core、Jackson序列化库、日志框架等等。如果没有Maven自动处理传递依赖你光是手动找齐这些jar包就能崩溃。另外Spring AI的版本更新跟普通框架不一样。它有很多个版本线并行推进比如Spring AI 1.0.0 GA版、Spring AI 2.0.0快照版还有Spring AI Alibaba的独立版本线。不同的版本对应不同的API用法和依赖坐标。Maven的版本管理机制能让你清晰地锁定某一个具体版本避免团队协作时出现你用的是老版本API、我用的是新版本的撕裂局面。1.2 Maven与Gradle的选择逻辑总有新手问Gradle不是更快吗为什么Spring AI的教程都默认用Maven说实话Gradle在构建速度上确实有优势尤其是大项目增量构建的时候。但Spring AI官方文档和示例工程绝大多数都是基于Maven的pom.xml来展示依赖坐标。你拿Gradle去套官方文档需要手动把Maven坐标换算成Gradle的implementation格式。Markup语言不同依赖版本声明方式也不同新手在换算过程中最容易出错——比如把spring-ai-alibaba的Maven坐标抄成Gradle格式但版本号被Maven的${version}占位符替换结果构建失败。我的建议是在Spring AI这个生态里老老实实用Maven。除非你对Gradle本身已经非常熟否则不要在这个阶段增加额外变量。2. Maven依赖下载失败的核心原因与仓库配置方案2.1 默认中央仓库为什么经常让人抓狂Maven默认的中央仓库Maven Central Repository服务器在海外。国内网络环境下下载一个几十MB的jar包经常出现连接超时、下载到一半失败、或者速度只有几KB每秒的情况。更麻烦的是如果下载中断Maven本地仓库里会留下一个.lastUpdated后缀的临时文件下次构建时会误以为依赖已经存在直接报找不到依赖。这个问题的根治方案是配置镜像仓库。国内可用的Maven镜像源有很多阿里云仓库是目前个人开发者和中小企业用得最多的一个。配置方式很简单打开Maven安装目录下的conf/settings.xml文件在mirrors节点里添加镜像配置mirror idaliyunmaven/id mirrorOfcentral/mirrorOf name阿里云公共仓库/name urlhttps://maven.aliyun.com/repository/public/url /mirror配置好之后Maven下载依赖时就会优先走阿里云镜像速度提升明显。2.2 只配中央仓库镜像还不够Spring AI的特殊仓库需求这里要提醒一个很多教程没讲到的坑Spring AI的某些快照版本和里程碑版本并不在Maven中央仓库里而是在Spring官方的里程碑仓库Spring Milestones Repository里。如果你在pom.xml里引入了spring-ai-openai-spring-boot-starter的1.0.0-SNAPSHOT版本只配了阿里云镜像还是不够的。你需要在pom.xml里显式声明Spring的仓库地址repositories repository idspring-milestones/id nameSpring Milestones/name urlhttps://repo.spring.io/milestone/url snapshots enabledfalse/enabled /snapshots /repository repository idspring-snapshots/id nameSpring Snapshots/name urlhttps://repo.spring.io/snapshot/url releases enabledfalse/enabled /releases /repository /repositories如果你用的是Spring AI Alibaba还需要留意它是否依赖了Spring Cloud Alibaba的仓库。最稳妥的做法是先在官方文档确认你选的版本属于哪个发布线GA、Milestone还是Snapshot再决定是否要添加对应仓库。2.3 settings.xml里的多镜像配置策略有的公司内网会有自己的私有仓库比如Nexus里面放着一些内部封装好的依赖。这种情况下你不能只用阿里云一个镜像而是要把私有仓库和公共镜像组合起来。一个实际可行的做法是在settings.xml里配置多个mirror并用mirrorOf指定不同镜像覆盖不同的仓库ID。比如mirror idinternal-nexus/id mirrorOfinternal-repo/mirrorOf urlhttp://your-nexus.com/repository/maven-public//url /mirror mirror idaliyunmaven/id mirrorOf*/mirrorOf urlhttps://maven.aliyun.com/repository/public/url /mirror这样配置后如果你在pom.xml里声明了repositoryidinternal-repo/idMaven会优先走内网私有仓库其他所有依赖则统一走阿里云镜像。3. IDEA中Maven依赖爆红的完整排查链路3.1 从现象到根因依赖爆红的四种典型场景IDEA中Maven依赖爆红是最容易让新手崩溃的场景。我在实际使用中总结出四种典型情况场景一本地仓库里根本没有这个依赖。这种情况最直接检查settings.xml里的本地仓库路径是否正确IDEA的Maven配置是否指向了那个settings.xml。场景二本地仓库里有依赖但版本不匹配。比如你本地已经缓存了spring-ai-openai-spring-boot-starter的0.8.1版本但pom.xml里写的是1.0.0-M1Maven会重新去远程下载如果远程下载失败爆红就出现了。场景三IDE的索引和缓存出问题。IDEA的Maven索引如果损坏即使本地仓库有正确的依赖面板里也可能显示爆红。这个问题很隐蔽我会在后面的小节专门说。场景四传递依赖冲突。Spring AI的某些版本会依赖一个特定版本的spring-core如果你的项目里其他库强制指定了另一个版本Maven的依赖仲裁机制会选择一个版本但IDEA可能在代码层面标红提示找不到某个类。3.2 逐步排查命令不要只靠IDEA面板遇到爆红我强烈建议你在命令行里先跑一遍Maven命令而不是直接盯着IDEA看。因为命令行输出的错误信息比IDEA的红色波浪线详细得多。比如在项目根目录执行mvn -U clean compile -X-U参数强制更新快照版本-X输出详细调试日志。然后查看日志中类似这样的关键信息Downloading from aliyunmaven: ...说明Maven正在从阿里云镜像下载Could not resolve dependencies for project ...说明哪个依赖解析失败The following artifacts could not be resolved: ...直接告诉你哪些jar包找不到。如果日志显示Downloaded from aliyunmaven但本地仓库里还是没有此时需要检查本地仓库目录结构。默认情况下本地仓库在用户目录下的.m2/repository你可以手动去看对应路径下有没有jar包和.lastUpdated文件。遇到.lastUpdated残留直接删除对应目录然后重新执行命令mvn -U clean compile3.3 IDEA中强制刷新与索引重建的骚操作命令行构建没问题但IDEA里还是爆红九成是IDEA的Maven索引缓存坏了。这时可以依次尝试下面三招点击Maven面板里的Reload All Maven Projects按钮圆形箭头图标重新加载项目如果不是索引损坏尝试File - Invalidate Caches and Restart等待IDEA重启后重新索引确认IDEA中Maven的settings.xml路径是否正确File - Settings - Build, Execution, Deployment - Build Tools - Maven核对User settings file和Local repository。第三个步骤看似无关紧要但非常容易出问题。很多人的IDEA默认用的是内置Maven配置而命令行使用的是你自己配的settings.xml。两边不一致就会导致IDEA里下载依赖的路径和命令行完全不一样。3.4 IDEA新建Maven项目时archetype怎么选IDEA的New Project界面里有一个Create from archetype选项很多新手不知道该怎么选。这里说清楚如果你只是想要一个最普通的Maven项目不要勾选Create from archetype。选Maven - Next直接填groupId和artifactId就行。如果你要创建Web项目可以选择org.apache.maven.archetypes:maven-archetype-webapp。但如果你是做Spring AI项目我的建议是直接选Spring Boot的初始化方式比如通过Spring Initializr创建或者先创建一个普通Maven项目然后手动在pom.xml里引入Spring AI依赖。原因很简单Spring AI项目本质上还是一个Spring Boot应用用官方的Spring Initializr生成项目骨架能自动配好spring-boot-starter-parent和对应的插件版本后面加Spring AI依赖会省很多事。4. Spring AI依赖坐标怎么选版本线、模块名与实际测试4.1 Spring AI的版本线拆解这是本篇最有价值的部分。Spring AI的版本号乍看很乱但捋清楚之后其实很有规律。Spring AI从2024年开始发布GA版本目前主线已经演进到了1.0.xSpring AI 2.0也在开发中。版本线主要分为GA版本如1.0.0、1.0.1稳定性高适合生产环境使用里程碑版本Milestone如1.0.0-M1包含新功能但API可能还会变快照版本Snapshot如1.0.0-SNAPSHOT每天甚至是每次提交都会更新不建议学习阶段使用。如果你是新接触Spring AI优先选最新的GA版本。怎么查直接打开https://spring.io/projects/spring-ai看官方文档标记的当前版本号或者看https://repo1.maven.org/maven2/org/springframework/ai/spring-ai-openai-spring-boot-starter/目录下的版本列表。4.2 核心依赖模块该引哪几个jar包这里我用一个表格来展示Spring AI最常用的几个核心模块模块坐标作用spring-ai-openai-spring-boot-starter集成OpenAI API的核心起步依赖封装了聊天、嵌入、图像生成等能力spring-ai-ollama-spring-boot-starter连接本地Ollama推理服务的起步依赖spring-ai-alibaba阿里云通义千问模型的Spring AI适配模块spring-ai-coreSpring AI的核心抽象大部分情况下会被上面的模块传递引入spring-ai-pdf-document-reader读取PDF文档用于RAG场景spring-ai-tika-document-reader基于Apache Tika解析各类文档用于知识库场景一个常见的误区是有的教程会让你把spring-ai-core和其他模块一起显式引入。实际上只要你引入了对应的starter模块spring-ai-core会自动传递依赖下来不需要手动添加。手动添加反而容易造成版本冲突。4.3 Spring AI Alibaba和通义千问的依赖配置实例如果你打算接入阿里云通义千问选Spring AI Alibaba是最近名方向。它在Maven中央仓库的坐标比较特殊不是用org.springframework.ai开头而是用com.alibaba.cloud.ai作为groupId。在pom.xml里添加依赖时通常还需要引入一个BOMBill of Materials来统一管理版本dependencyManagement dependencies dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-bom/artifactId version1.0.0-M3.1/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement然后引入具体的模块比如dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-starter/artifactId /dependency不熟悉BOM机制的读者可能不知道BOM的作用就是省去你在每个依赖上都写版本号。只要在dependencyManagement里声明了BOM后面的依赖就不用再写version了。这样做的好处是版本统一可控组件升级时只需要改BOM版本不用逐个改依赖。4.4 Spring AI连接本地部署的DeepSeek依赖只需要一个最近DeepSeek特别火很多人想用Spring AI连接本地部署的DeepSeek模型。实际操作起来比想象中简单得多。如果你本地部署的是DeepSeek官方提供的API服务兼容OpenAI协议那么直接用spring-ai-openai-spring-boot-starter就行然后在application.yml里把base-url改成你的DeepSeek服务地址spring: ai: openai: base-url: http://localhost:8000 api-key: not-needed chat: options: model: deepseek-chat这里api-key可以随便填一个占位符因为本地服务的鉴权一般不会认真校验。如果你是通过Ollama方式本地跑的DeepSeek模型那么依赖换成dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-ollama-spring-boot-starter/artifactId version1.0.0/version /dependency配置改为spring: ai: ollama: base-url: http://localhost:11434 chat: options: model: deepseek-r1:7b类似的思路对于任何OpenAI兼容的服务都适用这是Spring AI抽象层做得好的地方你换模型供应商只需要改配置和依赖业务代码几乎不用动。4.5 Spring AI中Skill、Advisor等扩展模块Spring AI在1.0之后除了基础的ChatClient之外还引入了Skill和Advisor这类更上层的抽象。Skill可以理解为一个预定义好的工具函数封装让模型具备调用外部工具的能力。例如你可以定义一个Tool注解的方法让AI模型在需要查询天气时自动调用这个Java方法。Component public class WeatherTools { Tool(description 根据城市名查询天气) public String getWeather(String city) { // 调用天气服务API return 晴天25度; } }然后把这个工具注册到ChatClient里模型就会在对话过程中自动判断是否需要调用这个工具。这是Spring AI 2.0里重点推的能力但它必须依赖正确版本的框架模块。如果你用的是1.0之前的版本Tool注解的包路径都不一样写代码时很容易踩坑。5. 依赖下载速度慢、报错时的终极兜底方案5.1 版本冲突时怎么快速定位Maven的依赖冲突处理逻辑是就近优先——谁在pom.xml里声明得越靠前谁就更容易被选为最终版本。但实际项目中依赖传递关系往往很复杂。排查冲突最有效的命令是mvn dependency:tree它会把整个项目的依赖树打印出来。你可以在输出里搜索冲突的包名看它被哪些模块引入最终解析到了哪个版本。比如你的项目里引入了spring-ai-alibaba-starter和某个内部SDK而这两个包同时依赖了不同版本的fastjson2。这时候你可以在pom.xml里显式指定一个版本号覆盖掉传递依赖里的版本dependency groupIdcom.alibaba.fastjson2/groupId artifactIdfastjson2/artifactId version2.0.50/version /dependency在dependencyManagement里声明版本是更规范的做法因为这样其他模块传递依赖时也会参考这个版本。5.2 Maven下载失败终极兜底方案之手动安装jar包有时候因为公司网络限制镜像仓库也连不上或者某个依赖在公开仓库里压根找不到。这时就需要手动把jar包安装到本地仓库。假设你手头有一个aliyun-sdk-oss-3.17.4.jar想安装到本地Maven仓库只需要执行mvn install:install-file -Dfile/path/to/aliyun-sdk-oss-3.17.4.jar -DgroupIdcom.aliyun.oss -DartifactIdaliyun-sdk-oss -Dversion3.17.4 -Dpackagingjar装完之后你的pom.xml里就可以正常声明依赖了。这个方法特别适合那些公司内网私有SDK、或者Maven中央仓库已被移除的老版本jar包。5.3 从IDEA的Maven面板查看依赖归属IDEA右侧的Maven面板里有一个Show Dependencies按钮点开之后可以图形化查看整个依赖关系图。这个图比mvn dependency:tree更直观但信息量大的时候视图会非常乱。对于新手我建议还是先用命令行的方式因为输出的文本信息更容易按关键字搜索定位。等你熟悉了依赖冲突的模式之后再用IDEA的可视化面板提高效率。6. 避坑经验Spring AIMaven开发中那些文档里没写的细节6.1 JDK版本和Maven版本必须配套Spring AI 1.0以上的版本要求JDK 17及以上。如果你的机器上安装的是JDK 8Maven构建时就会报错提示invalid source release: 17或类似的错误。而且Maven本身也有版本要求。Maven 3.6.0以下的版本对JDK 17的支持并不好有时候会出现诡异的编译问题。我的建议是JDK安装17或21LTS版本Maven安装3.9.x或更新的稳定版在命令行执行mvn -v查看当前Maven版本和它使用的Java版本。如果发现Maven用的是老版本JDK需要检查JAVA_HOME环境变量有没有指向正确的JDK路径。6.2 Windows和Mac下Maven环境变量的配置差异Windows下配置Maven环境变量需要在系统环境变量里新建MAVEN_HOME指向Maven解压目录然后在Path变量里加上%MAVEN_HOME%\bin。Mac下相对简单编辑~/.zshrc或~/.bash_profile文件加上export MAVEN_HOME/path/to/apache-maven-3.9.9 export PATH$MAVEN_HOME/bin:$PATH然后执行source ~/.zshrc让配置立即生效。Windows用户需要注意一个典型问题如果同时安装了多个版本的JDKJAVA_HOME优先指向哪个版本Maven就用哪个版本。建议在命令行里用echo %JAVA_HOME%检查当前值确认无误后再执行Maven命令。6.3 本地仓库的\陌生人.lastUpdated文件清理口诀Maven下载依赖失败时本地仓库会留下一个.lastUpdated文件。这个文件的坑在于Maven认为这个依赖已经尝试过了短时间内不会再次去远程下载导致即使网络恢复了依赖还是显示找不到。最直接的解决办法就是找到对应目录删除里面的.lastUpdated文件和_remote.repositories文件然后重新构建。如果你嫌手动找太麻烦可以用一行命令全盘清理find ~/.m2/repository -name *.lastUpdated -type f -delete清理之后再执行mvn -U clean install基本就能解决问题。要是连-U都拉不下来那大概率是远程仓库地址配置有问题或者网络根本不通需要回到镜像配置的环节去排查。6.4 IDEA中Maven面板正常但代码层爆红的诡异场景有时候Maven面板里的依赖树显示正常没有红色波浪线但代码里import某个类时IDEA依然标红。这种诡异情况多半是IDEA的编译信息没同步。解决办法是在IDEA的File - Settings - Build, Execution, Deployment - Compiler里勾选Build project automatically然后把Delegate IDE build/run actions to Maven选项打开。这样IDEA在编译时会直接调用Maven而不是使用自己内置的编译器能在很大程度上保持和命令行构建的一致性。还有一个方法是执行mvn clean compile之后在IDEA里重新导入整个项目。先关闭项目删除项目根目录下的.idea文件夹和所有.iml文件重新打开项目让IDEA完全重新索引。这个过程比较粗暴但确实能解决大部分怎么刷新都不对的问题。7. Spring AI项目的完整构建验证从空目录到Hello World7.1 全过程步骤展示说再多的理论不如亲手跑一遍完整流程。下面是我在本地实测过的从零创建Spring AI项目的全过程第一步创建一个普通的Maven项目不勾选archetype目录结构如下spring-ai-demo ├── pom.xml └── src └── main ├── java │ └── com/example/demo │ └── DemoApplication.java └── resources └── application.yml第二步在pom.xml里添加Spring Boot的父工程依赖和Spring AI的依赖。这里用Spring Boot 3.3.x Spring AI 1.0.0做演示parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.3.5/version relativePath/ /parent properties java.version17/java.version spring-ai.version1.0.0/spring-ai.version /properties dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-openai-spring-boot-starter/artifactId version${spring-ai.version}/version /dependency /dependencies第三步在application.yml里配置OpenAI兼容的接口地址和模型名称server: port: 8080 spring: application: name: spring-ai-demo ai: openai: base-url: https://api.openai.com api-key: ${OPENAI_API_KEY} chat: options: model: gpt-4o-mini第四步写一个最基础的控制器调用Spring AI的ChatClient进行对话RestController public class ChatController { private final ChatClient chatClient; public ChatController(ChatClient.Builder builder) { this.chatClient builder.build(); } GetMapping(/chat) public String chat(RequestParam String message) { return chatClient.prompt().user(message).call().content(); } }第五步执行Maven命令验证构建mvn clean package如果这一步能顺利通过说明Maven配置和依赖解析都没有问题。如果这一步爆红回头检查你的settings.xml和版本号是否拼写正确。7.2 验证构建产物是否完整构建成功后在target目录下会生成一个可执行的jar包。用java -jar target/spring-ai-demo-0.0.1-SNAPSHOT.jar启动应用浏览器访问http://localhost:8080/chat?message你好如果返回正常的AI回答说明整个项目已经跑通了。到这里Spring AI开发最基础、也最容易卡壳的环境搭建部分就算彻底解决了。后面的路就顺了。我在实际开发中体会最深的一点是Spring AI这个框架本身进步速度极快今天写的依赖坐标可能过两三个月就有新版本发布。所以一定要养成查看官方文档的习惯而不是照抄某篇博客的坐标就完事。Maven的报错信息虽然看着吓人但只要你掌握了mvn dependency:tree、mvn -X和.lastUpdated清理这几板斧绝大多数依赖问题都能自己解决。最后再分享一个小技巧pom.xml里写完依赖之后养成先执行mvn dependency:tree再写代码的习惯。这个命令能帮你提前发现版本冲突和依赖缺失省去后面一堆调试的麻烦。祝各位都能顺利跑通自己的第一个Spring AI应用。