尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Spring AI依赖下载失败?Maven配置Spring里程碑仓库全攻略

Spring AI依赖下载失败?Maven配置Spring里程碑仓库全攻略 1. 问题根源为什么明明写了依赖Maven 却一直报错先说结论spring-ai-openai-spring-boot-starter这个依赖下载不下来99% 的情况不是网络问题也不是坐标写错了而是你用的版本没有发布到 Maven 中央仓库。Spring AI 项目从 2023 年启动到 2025 年 5 月才正式发布 1.0.0 GA。在这之前所有版本——包括 0.8.x、1.0.0-M1 到 M6——都只发布到 Spring 自己的独立仓库里。Maven 默认只连 Maven Central中央仓库中央仓库里根本没有这些版本所以一旦你写了1.0.0-M6或者0.8.1这种版本号构建工具就会直接给你一个Could not find artifact的错误。很多人在这一步会先去检查 IDEA 的代理设置、清理本地仓库、甚至重装 Maven结果折腾一晚上还是不行。原因很简单本地仓库和网络都没问题问题是你要找的东西不在默认仓库里。这就好比你在一家超市里找一款只在另一个城市发售的限量商品超市本身没毛病但你得知道去哪家店才能买到。这个项目标题里的场景应该用的是1.0.0-M6之类的里程碑版本或者官方文档推荐的最新快照版本。下面我把完整的原因、正确配置和所有坑都梳理一遍照着做基本十分钟内解决。2. 先搞清楚版本号背后的发布策略2.1 Spring AI 的版本都发布在哪里Spring 生态的大部分项目都遵循一套固定的发布节奏正式版GA进 Maven Central里程碑版M系列和快照版SNAPSHOT进repo.spring.io。Spring AI 在 1.0.0 GA 之前也不例外而且因为项目发展快它的里程碑版本用得特别频繁很多教程和示例代码里用的都是 M 系列版本。拿我自己的项目举例今年年初我用的是1.0.0-M6这个版本对应 Spring Boot 3.4.x功能上已经比较完整了但那会儿它只存在于 Spring 的里程碑仓库。如果你直接往pom.xml里写这个版本号Maven 会去中央仓库找找不到就报错。你需要做的就是在 Maven 的仓库列表里补上 Spring 的里程碑仓库地址。到 2025 年 5 月Spring AI 1.0.0 正式版发布了如果你的项目用的是这个版本理论上不需要额外配置仓库。但实际工作中项目里还大量存在用 M 系列版本的老工程而且新版本的稳定性和兼容性也需要你根据实际需求决定要不要升级。所以两种场景我都讲清楚。2.2 版本与仓库的对应关系速查版本类型版本号示例发布仓库是否需要额外配置GA 正式版1.0.0Maven Central不需要里程碑版1.0.0-M6、0.8.1repo.spring.io/milestone需要快照版1.0.0-SNAPSHOTrepo.spring.io/snapshot需要且仓库需要开启快照支持历史版本0.8.1repo.spring.io/milestone需要这里有个容易混淆的点0.8.1虽然看起来像个稳定版本号但它并不是 GA 发布而是 1.0.0 之前的预发布版本所以也在里程碑仓库里。判断一个版本是否在中央仓库最快的方法是直接打开 Maven Central 的搜索页面搜spring-ai-openai-spring-boot-starter看看有没有你用的版本号。没有的话直接去配仓库就对了。3. Maven 项目正确配置 Spring 里程碑仓库3.1 最简配置pom.xml 加 repositories在pom.xml的project标签里找到repositories节点把下面的内容加进去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如果你的pom.xml里原本没有repositories节点就在properties和dependencies之间新建一个。如果已经有其他仓库比如阿里云镜像把这段追加进去不要覆盖原有配置。配置里有两个细节需要说明第一snapshotsenabledfalse/enabled/snapshots的意思是这个仓库只用于拉取里程碑版本不允许从它这里拉取快照版本。Maven 默认对快照的处理和正式版本不同如果你不关闭快照构建时可能会因为拉取不存在的快照版本而报额外的错误。第二仓库 ID 建议保持spring-milestones和spring-snapshots不变。这个 ID 不仅仅是标识符还对应settings.xml里可能配置的镜像规则。如果你公司内部有私服ID 冲突会导致仓库被镜像拦截后面排查部分我会详细说。3.2 用 Docker 镜像或 WSL 环境时要确认 Maven 配置如果你和我一样项目是放在 Docker 容器里构建的或者用的是 WSL 环境要记得 Maven 的配置文件路径可能和你本机的 IDEA 配置不是同一个。IDEA 里配置的settings.xml只对 IDEA 的构建过程生效命令行mvn package用的是~/.m2/settings.xml。有一次我在 IDEA 里构建一切正常切到命令行用 CI 脚本跑就报找不到依赖排查了半天才发现是容器的 Maven 没有配 Spring 仓库。所以如果你是复现同事的报错先问清楚他用的是 IDEA 还是命令行或者说你需要在所有会用到的 Maven 环境里都加上同样的仓库配置。3.3 配置完记得强制刷新依赖改完pom.xml后IDEA 右上角会出现一个刷新按钮点击刷新。如果你用的是命令行建议加上-U参数强制检查远程仓库的最新状态mvn clean compile -U-U参数会强制 Maven 检查所有远程仓库的更新避免本地已经有失败的缓存记录导致 Maven 直接跳过下载。这个参数在切换仓库配置后非常关键因为 Maven 对下载失败的内容会缓存一份记录叫做_remote.repositories不强制刷新的话它会认为这个依赖之前已经尝试过并且失败了直接跳过。4. Gradle 项目build.gradle 里的仓库配置4.1 Groovy DSL 配置方式如果你用的是 Gradle在build.gradle文件的repositories块里加上这两个仓库repositories { mavenCentral() maven { url https://repo.spring.io/milestone } maven { url https://repo.spring.io/snapshot } }注意顺序mavenCentral()放在最前面让 Gradle 优先从中央仓库查找只有找不到的版本才会进入 Spring 仓库。这个顺序本身对结果没太大影响因为 Gradle 会在所有仓库里依次搜索直到找到为止但习惯上把更通用的仓库放前面可以减少不必要的远程请求。配置完之后执行gradle clean build --refresh-dependencies--refresh-dependencies和 Maven 的-U参数作用类似强制刷新所有依赖的缓存状态特别是在你之前已经遇到下载失败的情况下。4.2 Kotlin DSL 配置方式Kotlin DSL 的写法也差不多只是语法上有点差异repositories { mavenCentral() maven { url uri(https://repo.spring.io/milestone) } maven { url uri(https://repo.spring.io/snapshot) } }有一点需要提醒如果你的项目中同时使用了 Spring Boot Gradle Plugin 或者其他 Spring 生态的插件某个插件版本本身也可能发布在 Spring 仓库里。这种情况下你不仅要在repositories里配置仓库还要在pluginManagement或plugins块的pluginRepositories里加上同样的地址。否则依赖能拉到插件还是会报错。完整的做法是这样的pluginManagement { repositories { mavenCentral() gradlePluginPortal() maven { url uri(https://repo.spring.io/milestone) } maven { url uri(https://repo.spring.io/snapshot) } } }这个细节很多教程不会提但实际踩过坑的人都知道插件下载失败和依赖下载失败的表现形式完全不同报错信息会直接指向插件的坐标有时候不会提示你加仓库而是让你检查网络。如果你遇到插件下载失败先看看是不是用了 Spring 发布的插件版本。5. 排查流程配置完还是下载不了的问题清单5.1 常见报错信息与对应处理方式我在实操过程中收集了一份报错速查表照着这个排查效率会高很多报错关键词原因解决办法Could not find artifact org.springframework.ai:spring-ai-openai-spring-boot-starter:jar:1.0.0-M6仓库没配或版本号写错检查 pom.xml 的 repositories 和版本号Failed to collect dependencies...Maven 依赖解析中断加了-U强制刷新后重试Cannot resolve external dependency...Gradle 无法解析检查 Gradle 仓库配置执行--refresh-dependenciesPKIX path building failed证书问题或公司网络做了 HTTPS 拦截先排除仓库配置问题再处理证书Return code is 409: Conflict仓库 ID 冲突或私服镜像拦截检查 settings.xml 的 mirrorOf 规则Cannot access spring-milestones in offline mode设置了离线模式检查是否开启了mvn -o或 IDEA 的 offline 选项第一条是最常见的看到Could not find artifact基本可以断定是仓库配置问题。第二条和第一条经常一起出现本质是一样的。后面几条是排查了更多项目之后总结出来的隐蔽问题。5.2 最容易忽略的坑镜像拦截与仓库 ID 冲突很多公司内部都有 Nexus 私服settings.xml里会配置一段 mirror 规则。最常见的写法是mirror idnexus/id mirrorOf*/mirrorOf urlhttps://nexus.example.com/repository/maven-public//url /mirrormirrorOf的值是*意思是所有仓库请求都被转发到私服地址。这种情况下你在pom.xml里配置的spring-milestones仓库地址根本不会被访问Maven 会把请求转发到私服的公共仓库。如果私服没有同步 Spring 的里程碑仓库那结果是你在pom.xml里加了仓库但完全不起作用。解决办法有两条路一是修改私服配置在 Nexus 里添加一个远程仓库指向https://repo.spring.io/milestone然后把这几个仓库组到同一个 public group 里。这个要在 Nexus 的 Web 界面操作让管理员处理。二是在本地绕过镜像规则把mirrorOf改成排除指定 IDmirror idnexus/id mirrorOf*,!spring-milestones,!spring-snapshots/mirrorOf urlhttps://nexus.example.com/repository/maven-public//url /mirror*,!spring-milestones,!spring-snapshots的含义是除了spring-milestones和spring-snapshots这两个仓库之外其他仓库请求都走私服。这样本地配置的 Spring 仓库就能直接访问了。这个技巧是我在排查一个客户项目时发现的当时他们把 Spring 仓库配好之后还是下载不了我在他们settings.xml里看到mirrorOf是*改完立竿见影。5.3 阿里云镜像能不能用来下载 Spring AI关于阿里云镜像我实测过几次结论是这样的阿里云公共仓库能同步大部分 Maven Central 的依赖但 Spring 的里程碑仓库是独立的托管系统阿里云是否会同步取决于它那边的配置。实测下来有些版本能拉到有些版本拉不到不太稳定。所以我的建议是不要依赖阿里云镜像来解决 Spring AI 的下载问题。直接配置官方仓库是稳定可靠的做法。如果你本来就配置了阿里云镜像作为中央仓库的加速通道保留它没问题但 Spring 里程碑仓库必须单独配置而且需要确保镜像规则没有拦截它。5.4 清理本地仓库的失败缓存这个方法虽然听起来简单但能解决很多奇怪的问题。Maven 在下载依赖失败后会在本地仓库里留下一个.lastUpdated后缀的文件。这个文件记录了最后一次下载失败的时间戳Maven 在短时间内不会再重复尝试下载同一个依赖。你改了配置之后如果不清理这些文件Maven 可能会直接跳过下载。清理方法很简单找到对应依赖的目录删掉rm -rf ~/.m2/repository/org/springframework/ai或者在 Windows 上直接去本地仓库目录找到org.springframework.ai文件夹删掉。删完之后重新构建Maven 会重新解析并下载。这也是为什么-U参数那么重要它会忽略.lastUpdated文件的限制强制重新尝试下载省去手动清理的麻烦。6. 版本选择与依赖管理从源头规避下载问题6.1 用 BOM 统一管理版本如果你在项目里同时用到多个 Spring AI 的模块比如spring-ai-openai、spring-ai-pdf-document-reader、spring-ai-tika-document-reader建议用 BOMBill of Materials统一管理版本避免每个模块单独写版本号导致版本冲突。引入 BOM 的方式如下dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version1.0.0-M6/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagementBOM 的作用是声明一组依赖的推荐版本引入之后你只需要声明具体的依赖坐标不需要写版本号dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-openai-spring-boot-starter/artifactId /dependency这样做的好处有两个第一是减少版本号维护成本所有 Spring AI 模块保持一致第二是避免某些模块写错版本号导致解析失败。BOM 本身也发布在同一个仓库里所以配置仓库和配置普通依赖是一样的。6.2 要不要升级到 1.0.0 GASpring AI 1.0.0 正式版发布之后如果你是新项目我建议直接上 1.0.0。原因很简单GA 版本在 Maven Central 上不需要任何额外仓库配置团队协作时少了配置环节踩坑概率直线下降。如果你已经在用 M 系列版本且项目跑得好好的那也没必要急着升。我遇到过的情况是从一个 M 版本升到另一个 M 版本某些 API 变了需要改代码这种升级成本比配置仓库的成本高得多。除非你遇到了无法绕过的 bug或者需要新版本才有的功能否则先稳住把时间和精力放在业务上。当然如果你停留在 M 系列版本那你必须保留仓库配置这个问题在项目生命周期内会一直存在。6.3 仓库配置的完整示例模板这里给一份完整的、可以直接复制使用的 Mavenpom.xml模板方便你对照检查?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.4.1/version relativePath/ /parent groupIdcom.example/groupId artifactIdspring-ai-demo/artifactId version0.0.1-SNAPSHOT/version properties java.version17/java.version spring-ai.version1.0.0-M6/spring-ai.version /properties 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 dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version${spring-ai.version}/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-openai-spring-boot-starter/artifactId /dependency /dependencies /projectSpring Boot 父 POM 的版本要和 Spring AI 版本匹配我用3.4.1搭配1.0.0-M6是经过实测的这两个版本在功能上配合良好。7. 实操心得几次踩坑后总结的方法论7.1 先判断是仓库问题还是依赖本身的问题遇到依赖下载失败我现在的排查顺序是固定的先去 Maven Central 搜索页面或repo.spring.io的目录列表确认这个版本是否存在然后检查本地pom.xml的仓库配置再看settings.xml的镜像规则最后才考虑网络和证书。这个顺序能筛掉九成的问题。判断版本存在与否有个取巧的办法直接访问仓库目录列表。比如打开https://repo.spring.io/milestone/org/springframework/ai/spring-ai-openai-spring-boot-starter/能看到所有发布的版本列表。如果里面有你要的版本号那说明版本没问题问题在配置如果列表里压根没有这个版本那就是版本号写错了。7.2 不要盲目升级依赖版本有一次我为了省去仓库配置的麻烦直接把版本从1.0.0-M6升到1.0.0结果代码里调用的OpenAiChatModel的几个方法签名变了编译报错。改代码花了大半天时间还不如当初老老实实配仓库。所以我的建议是如果项目已经跑通了仓库配置这种东西属于一劳永逸的活配好一次以后都不用管没必要为了省一次配置去承担版本升级的代码迁移成本。7.3 最后再分享一个小技巧用 IDEA 开发时在pom.xml里写完仓库配置后如果你发现依赖还是加载不出来可以试试 IDEA 右侧 Maven 面板里的Reload All Maven Projects按钮注意不是左下角的自动导入了。有时候 IDEA 的自动导入不会实时响应pom.xml的repositories变更手动触发一次全量重载最靠谱。确定依赖最终加载成功后再跑一次mvn dependency:tree看看依赖的关系树是否完整这能帮你在项目启动前就发现潜在的 jar 包冲突。这一步不是必须的但养成习惯后能省下很多运行时排查的时间。
返回列表