
昨天还有同事抱着电脑过来问为什么我在IDEA里配好了阿里云镜像今天新建一个Maven项目依赖还是从repo.maven.apache.org慢慢拉而且半天卡在0%。我一看就明白了他配的是“当前项目”的配置Maven运行时真正读取的镜像源配置文件——settings.xml——压根没动。这个现象太常见了尤其刚接触IDEA加Maven组合的开发者几乎都会在这里绕一圈。这篇就把Maven镜像源配置这件事彻底讲透镜像源该写进哪个文件、阿里云、清华、华为云怎么选、怎么写才能让这台电脑上所有项目包括以后新建的全局生效、配完怎么验证、以及最常见的几个坑分别是什么原因。不管是第一次配置的新手还是已经被Maven下载卡到怀疑人生的老手按这个思路走一遍基本能一次配到位。1. 先搞清楚Maven镜像配置的本体是settings.xmlIDEA只是调用方1.1 Maven到底在哪里读镜像配置很多人把IDEA当成Maven的“管理界面”觉得在IDEA里填了什么Maven就会照做。实际上Maven是一个独立的构建工具它自己有一套配置文件体系。当你在IDEA里点“刷新”或者“编译”时IDEA只是在后台调用Maven然后把Maven的输出显示在面板里。Maven真正读取的配置从来都是它自己的那两个settings.xml文件外加项目的pom.xml。这两个settings.xml分别是全局配置Maven安装目录/conf/settings.xml例如D:\apache-maven-3.9.6\conf\settings.xml用户配置用户目录/.m2/settings.xml在Windows上是C:\Users\你的用户名\.m2\settings.xmlmacOS和Linux上是~/.m2/settings.xmlMaven读取配置时会先读全局配置再读用户配置然后把两边合并起来形成一个“最终生效配置”。镜像规则就放在这两个文件里的mirrors节点中。你可以在命令行执行mvn help:effective-settings直接看到合并后的最终配置长什么样这是后面验证环节的核心命令。打个比方Maven是个采购员settings.xml是他手里的采购指南指南上写着“凡是去central仓库买货的订单全部改走阿里云仓库”。IDEA只是雇佣采购员干活的包工头负责告诉他用哪本指南但指南内容得你自己写好。1.2 为什么在IDEA面板上配置换个项目就失效常见的“配置完只对当前项目生效”的错觉来源主要有两个。第一个是把repositories写进了pom.xml。pom.xml里的仓库声明是项目级别的它只是告诉Maven“这个项目除了默认仓库之外还可以去哪些仓库找构件”。它影响范围只有当前这个pom及其子模块新建一个项目pom里没写这段自然就失效了。第二个原因是搞混了IDEA面板和settings.xml的关系。IDEA的Maven设置面板Settings Build, Execution, Deployment Build Tools Maven里其实没有让你直接填“镜像URL”的输入框它能配置的是三样东西Maven的安装路径、用户settings文件路径、本地仓库路径。你如果在网上看到某个教程让你在IDEA面板里填URL那多半是把Gradle的配置方式或者IDEA的其他功能记混了。真正决定“走哪个镜像”的只有settings.xml里mirrors节点的内容。这里还有个很隐蔽的坑IDEA的Maven设置面板本身是全局的改一次对所有项目都生效但你配置的“settings文件路径”和“本地仓库路径”未必是同一个。比如你改了~/.m2/settings.xml但IDEA的“User settings file”字段指向的是Maven安装目录里的另一份settings.xml那等于白改。所以配置完之后一定要回来看一眼IDEA到底在用哪个文件这点在后面章节会专门讲。2. 镜像源怎么选阿里云、清华TUNA、华为云哪个适合你2.1 主流的国内Maven镜像对比配置镜像之前先得解决“镜像源选谁”的问题。目前国内用得最多的几个镜像源我整理了一张表方便直接对照镜像源仓库地址覆盖范围适用场景阿里云公共仓库https://maven.aliyun.com/repository/publiccentral、jcenter、spring等公共依赖的聚合代理绝大多数国内开发者的默认选择社区资料最多阿里云centralhttps://maven.aliyun.com/repository/central仅代理Maven中央仓库公司内部已有Nexus只想给central加速清华TUNAhttps://mirrors.tuna.tsinghua.edu.cn/maven2/镜像Maven Central教育网内速度极好校外网络需实测华为云https://repo.huaweicloud.com/repository/maven/central及常规公共组件电信网络下表现不错华为云用户顺手用腾讯云https://mirrors.cloud.tencent.com/nexus/repository/maven-public/聚合公共仓库阿里云不可用时的备用方案个人开发、没有历史包袱的话我的建议很直接默认选阿里云公共仓库。它不是只做了中央仓库的一比一镜像而是在背后把central、jcenter、spring等常见源的数据都聚合进来缓存了一遍对绝大多数Java、Kotlin项目的依赖和插件都能覆盖一个地址解决绝大部分问题。清华TUNA适合教育网环境。如果你在学校实验室或者校园网里DNS解析和路由对教育网镜像有优待TUNA的速度能明显拉开差距。但出了教育网它和其他源相比没有绝对优势所以得看你的实际网络环境。华为云和腾讯云可以作为备用。这类大厂镜像的稳定性都不差选择上更多是“哪个网络环境访问快”的问题。判断方法也简单在浏览器里直接打开仓库地址能通、能列出目录再在命令行curl -I看下响应头哪个延迟低用哪个。2.2 mirrorOf的取值*、central、external:*分别是什么意思选好镜像源之后紧接着要决定mirrorOf标签的写法。这个标签的作用是告诉Maven“该把哪些仓库的请求劫持到镜像上来”。常见取值有三种mirrorOf*/mirrorOf匹配所有仓库包括pom.xml里自定义的仓库。最省心个人电脑强烈推荐。但要注意如果你公司有内部Nexus仓库这个写法会把发往内网的请求也劫持到镜像上导致内部构件拉不到。mirrorOfcentral/mirrorOf只劫持中央仓库的请求。中央仓库的id固定是centralMaven默认的插件仓库id也是central所以一个central就能把绝大多数依赖和插件都走镜像。公司内网环境推荐这种不会误伤内部仓库。mirrorOfexternal:*/mirrorOf匹配所有非本机的远程仓库也就是排除localhost和file://协议的仓库。这个写法看起来比*更精细但同样会把公司内网远程仓库劫持掉实际使用时需要谨慎。多仓库的写法用逗号分隔例如central,google。我的习惯是个人电脑、自己玩的项目用*加阿里云public公司项目、有内部仓库管理平台的用central加阿里云central。等你在公司环境吃过一次“内部构件被镜像劫持”的亏就会明白这个选择有多重要了。2.3 如果项目里显式声明了google仓库有些从Android或者Gradle迁移过来的项目pom.xml里会显式声明一个id为google的仓库。这种情况下如果你只配了mirrorOfcentral那么对google仓库的请求依然走直连国内访问依然很慢。解决办法是再加一个mirror节点单独把google仓库指到阿里云的google仓库地址mirror idaliyun-google/id urlhttps://maven.aliyun.com/repository/google/url mirrorOfgoogle/mirrorOf /mirror阿里云镜像还提供gradle-plugin、spring、spring-plugin、grails-core等细分仓库地址需要的时候都可以用同样的方式追加。不过对纯Maven项目来说上面的public聚合仓库基本够了这个google mirror属于“遇到再用”的补充项。3. 全局生效的两个配置落点用户级还是安装目录级3.1 两个settings.xml的位置和职责前文说过Maven的镜像配置可以放在两个settings.xml里它们都位于项目目录之外所以天然就是“对所有项目生效”的。但两者的职责和存储位置不一样用户级配置在系统当前用户的.m2目录下跟随操作系统用户。你换一个IDEA版本、换一个Maven版本甚至换一台电脑只要把这个文件拷过去配置就全部带过去了。我强烈建议把主要的镜像配置放在这个文件里因为它是“跟着人走”的最不容易丢。安装目录级配置在Maven解压目录的conf文件夹下。它跟随的是Maven这个安装包本身适合团队约定“大家统一用某个Maven发行包并统一配置”的场景。但它有个明显弱点IDEA自带的Bundled Maven实际上也有一套自己的conf/settings.xml藏在IDEA的安装目录中升级IDEA时存在被覆盖的风险所以我一般不建议新手去动它。这里还要说清楚合并规则Maven先读安装目录级配置再读用户级配置。两个文件里如果存在id相同的mirror后读取的用户级配置会覆盖全局配置id不同的mirror则会合并共存。所以“最终生效”的镜像并不一定是你刚改的那个文件里的那一条一定要用mvn help:effective-settings确认合并后的结果。3.2 IDEA里三个字段分别对应什么在IDEA的Settings Build, Execution, Deployment Build Tools Maven面板里有三个关键字段认识它们之后就不容易配错了。第一个是Maven home path也就是Maven的安装路径。这里可以选IDEA自带的Bundled Maven也可以选你本地自己装的Maven。我建议选择本地安装的Maven目录因为你能直接编辑它的conf/settings.xml而且命令行里mvn命令用的也是同一份两边行为一致。用Bundled Maven也不是不行但出了问题你很难定位配置文件到底在哪里。第二个是User settings file也就是用户级settings.xml的路径。默认指向~/.m2/settings.xml。你改完镜像配置之后务必回到这里确认路径没被指向别的文件。这就是前面说的“改了个寂寞”的根源。第三个是Local repository本地仓库的存放位置。它通常会自动从settings.xml里的localRepository节点读取如果你手动改过路径这里需要保持一致。另外提醒一下IDEA 2020之后的版本这几个字段默认是“继承”状态输入框是灰色的。要手动填写得先勾选字段后面的Override复选框否则你填的内容不会生效。这个细节很多人第一次会漏掉。3.3 命令行和IDEA必须用同一份配置如果你平时也会在终端敲mvn命令那么只要~/.m2/settings.xml配置正确命令行构建也会自动走同样的镜像因为Maven默认就会去读用户级配置。这是用户级配置最大的优点“一条配置两边通用”。但反过来也意味着一个隐患如果你安装目录级的conf/settings.xml里配了另一套镜像规则两边合并后可能互相干扰。比如全局配置里写了一个mirrorOf*的内网镜像用户配置里又写了一个mirrorOf*的阿里云镜像Maven只会按规则匹配其中一条最终走哪个取决于mirror的id和读取顺序。排查这类问题时别靠猜直接mvn help:effective-settings把最终结果拉出来看一目了然。4. 手把手写settings.xml并告诉IDEA去读含完整配置与验证4.1 操作前必做确认Maven位置和备份原文件开始动手之前先做两件小事能省掉后面一堆麻烦。第一确认本机的Maven到底在哪。在命令行输入mvn -v能看到Maven版本和MAVEN_HOME路径。如果提示“不是内部或外部命令”说明你没配环境变量但没关系你依然可以在IDEA的Maven设置面板里看“Maven home path”当前指向哪里记下这个路径。第二找到准备修改的settings.xml先复制一份备份出来。Windows下可以用copy settings.xml settings.xml.bakmacOS和Linux下用cp settings.xml settings.xml.bak。别嫌这一步多余——改坏XML之后这个备份就是你的后悔药尤其当你手滑删掉了某个标签又没注意到时恢复原文件永远比反推错误快。4.2 settings.xml完整示例下面这份配置可以同时完成两件事指定本地仓库位置并把所有仓库请求转发到阿里云公共仓库。你可以直接新建一个settings.xml如果.m2下还没有这个文件的话把内容粘贴进去?xml version1.0 encodingUTF-8? settings xmlnshttp://maven.apache.org/SETTINGS/1.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd !-- 本地仓库位置改成你希望存放依赖的磁盘目录 -- localRepositoryD:/maven-repository/localRepository mirrors mirror idaliyunmaven/id nameAliyun Public Repository/name urlhttps://maven.aliyun.com/repository/public/url mirrorOf*/mirrorOf /mirror /mirrors /settings逐个解释一下各标签的含义。localRepository指定本地仓库的磁盘路径默认是~/.m2/repository。如果你的C盘空间吃紧想换到D盘或者别的数据盘改这里最有效。路径分隔符推荐用正斜杠比如D:/maven-repository避免反斜杠被XML解析时当成转义字符处理。mirror节点的核心是四个子标签。id是这个镜像的唯一标识一定不要跟其他mirror重复否则后读取的会覆盖先读取的造成“我明明改了却不生效”的灵异事件。name是描述信息随便写。url是镜像的仓库地址必须写对。mirrorOf是命中规则个人开发写*即可把所有仓库请求全部转发到阿里云public。如果你用的是安装目录级的conf/settings.xml原文件里有一大堆注释掉的示例配置不需要全部删掉只需要把mirrors之间的内容替换成上面的配置就行。如果用的是用户级.m2/settings.xml而该文件原本不存在直接新建并粘贴上面内容也不会影响任何默认行为。4.3 让IDEA重新读取配置配置文件改完之后IDEA不会自动感知需要手动让它重新读取。回到IDEA的Maven设置面板确认三件事Maven home path指向你实际使用的MavenUser settings file勾选了Override并指向你刚修改的那个settings.xmlLocal repository与你设置的本地仓库路径一致。设置完点Apply。然后打开IDEA右侧的Maven工具窗口点击工具栏上的“Reload All Maven Projects”按钮也就是那个环形箭头图标。这个操作会触发IDEA重新读取settings.xml和pom.xml并把依赖列表刷新一遍。如果以后你发现改了settings.xml但构建行为没变化先别怀疑配置写错了大概率只是没有Reload。对于新建项目情况更简单。当你执行File New Project创建Maven工程时IDEA用的就是你全局配置的那套Maven设置archetype模板下载和后续的插件下载都会走你配置的镜像不用为每个新项目单独再配一遍。这也是“对所有项目生效”最直观的体现。4.4 验证三步走配置完成并Reload之后一定要验证别急着开始写代码。验证分三步每一步都很直观。第一步命令行进入任意Maven项目目录执行mvn help:effective-settings这个命令会让Maven把合并后的最终配置打印出来。在输出里搜索aliyunmaven如果能找到对应的mirror节点说明配置已经被Maven读到了。第二步执行一次真正的依赖解析来验证下载路径。在一个测试项目里运行mvn dependency:resolve观察控制台日志。如果看到类似Downloading from aliyunmaven: https://maven.aliyun.com/repository/public/...这样的输出说明请求确实走了镜像。第三步找一个依赖较多的项目执行mvn -U clean install-U参数会强制检查SNAPSHOT依赖的更新。比对一下配置前后的下载速度和成功率如果之前要十几分钟还经常失败现在几分钟内跑完那配置就算真正生效了。5. 配置完高频踩坑排查从Download日志倒推问题在哪5.1 现象A日志里怎么还是Downloading from central配置完以后最打击人的情况就是日志里依然出现Downloading from central: https://repo.maven.apache.org/maven2/。遇到这个现象按下面的顺序排查。先确认IDEA有没有真的重载配置。很多人改完文件忘点ReloadIDEA内存里还是旧配置这时候点击Maven工具窗口的“Reload All Maven Projects”就能解决。再核对IDEA实际读取的settings.xml路径。去看看User settings file字段如果它指向的是D:\apache-maven-3.9.6\conf\settings.xml而你改的是C:\Users\你\.m2\settings.xml那当然不生效。这种情况用mvn help:effective-settings对比一下命令行和IDEA的差异最容易暴露问题。接着看mirrorOf的匹配范围。如果你的镜像写的是mirrorOfcentral而pom.xml里显式声明了一个id为myrepo的仓库那么对myrepo的请求依然会直连。想全部走镜像就改成*或者把需要的仓库id都加进去。最后检查有没有多个mirror共用一个id。Maven的mirror合并规则里同id的mirror会互相覆盖如果你之前配置过一个id为aliyunmaven的镜像后来又加了一个同id但不同url的镜像后者的生效顺序取决于配置位置。把所有id改成唯一值能避免大部分“改了不生效”的谜案。5.2 现象BCould not transfer artifact或PKIX path building failed依赖解析失败时控制台经常出现两种错误Could not transfer artifact ... from/to aliyunmaven ...和PKIX path building failed: unable to find valid certification path。前者表示Maven连不上镜像地址常见原因是网络不通、公司防火墙拦截、或者镜像URL写错。先用浏览器或命令行curl -I https://maven.aliyun.com/repository/public测一下地址通不通。如果浏览器能开但Maven连不上检查一下IDEA或系统是否有代理设置Maven默认不走IDEA的代理得在settings.xml或MAVEN_OPTS里显式配置。后者是TLS证书校验失败意思是Maven在访问镜像时JDK的信任库cacerts里找不到对应的CA证书链。阿里云这类正规镜像正常情况下不会触发一旦出现多半是JDK版本太老、本地安全软件做了HTTPS拦截、或者公司用自建镜像加了私有证书。临时解法是在IDEA的Maven Importer VM options里加上-Dmaven.wagon.http.ssl.insecuretrue -Dmaven.wagon.http.ssl.allowalltrue -Dmaven.wagon.http.ssl.ignore.validity.datestrue这等于关闭证书校验适合快速绕过问题但不适合生产环境长期使用。正式做法是把对应CA证书导入JDK的cacerts或者直接换成新版本的JDK。5.3 现象C改完settings.xmlIDEA直接报XML解析错误如果settings.xml保存编码不对或者手写时标签没闭合、注释块没配对Maven在解析时就会报Content is not allowed in prolog或者parse error ... line XX。这个坑在Windows上尤其常见因为记事本默认可能把文件存成带BOM的UTF-8Maven对BOM非常敏感。建议用IDEA的XML编辑器打开settings.xml进行编辑有语法错误会直接标红能避免大部分低级错误。保存时注意编码选择UTF-8、且不带BOM。如果已经改坏了就用第4.1节留下的备份文件恢复然后重新改一遍。不要指望Maven“容错”它在这个问题上一点面子都不给。5.4 现象D本地仓库路径设置不当localRepository标签如果写了一个不存在的路径Maven通常会尝试自动创建但如果路径包含非法字符、权限不足或者写成了相对路径就可能出现Cannot create local repository at ...之类的错误。建议写绝对路径并确保该目录有读写权限。Windows上使用D:/maven-repository这样的写法最省心macOS和Linux直接用/Users/xxx/maven-repository或/home/xxx/maven-repository。改完本地仓库路径后原来旧仓库缓存不会自动迁移第一次构建会把依赖重新下载一遍这是正常现象不用紧张。5.5 关于IDEA Bundled Maven的最后建议最后聊一下IDEA自带的Bundled Maven。有些新手图省事Maven home path直接选了Bundled这是可以的但你要知道它的配置文件藏在IDEA安装目录下的plugins/maven/lib/maven3/conf/settings.xml里。改它能生效但IDEA升级时这个目录可能被整体重建配置就没了。更稳妥的做法是从Apache官网下载一份独立的Maven发行包解压到固定目录然后在IDEA里把Maven home path指向它。这样你能编辑的conf/settings.xml就在明面上不受IDEA升级影响。同时只要~/.m2/settings.xml里配置了镜像不管IDEA用的是Bundled Maven还是本地Maven都会读取用户级配置所以把主要镜像配置放在.m2下才是真正的“一劳永逸”。我现在每换一台电脑、重装一次系统第一件事就是把~/.m2/settings.xml这个文件复制进去它比任何IDE里的设置都可靠。你可以把这个文件丢到自己的dotfiles仓库里或者在公司内部知识库放一份模板新同事入职直接复制粘贴比当面讲十分钟配置步骤管用得多。配置本身不复杂但把“改哪个文件、为什么改、怎么验证”这三件事一次性搞清楚后面能少走很多弯路。