
1. 先搞明白Maven到底在替我们干什么1.1 构建工具解决了什么现实问题如果你第一次接触Maven可能已经在网上搜过“maven是干嘛的”这种问题。这句话问得没错但大部分人得到的答案是“项目管理工具”“构建工具”听完还是不知道它具体解决了什么。我用一个场景说明假设你写Java项目要用到Spring、MyBatis、Jackson这些第三方库。没有Maven的时候你要自己去官网下载每个jar包把jar包复制到项目的一个lib目录里再手动加到IDE的ClassPath里。项目里少下载一个jar、版本对不上、同事用的版本和你不一样项目就编译不过。这还算好的更麻烦的是jar包之间还有依赖关系比如你下载A.jar它内部又依赖B.jar的特定版本你根本不可能靠手工把这些依赖关系理清楚。Maven做的事情简单说就是两件帮你声明“我这个项目用了什么库、什么版本”然后它自动把对应的jar包下载到本地再把它们之间的依赖关系一起处理完。你不需要知道这些jar包具体放在哪儿不需要手动下载也不用担心漏掉谁。类比一下的话Maven在Java世界里就像npm在前端世界、pip在Python世界里的角色。不过Maven做得更多它不只是管理依赖还负责一套完整的构建流程。1.2 Maven的两大核心依赖管理 标准生命周期第一是依赖管理。项目里想用某个库只需要在pom.xml里写上一段坐标dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId version2.7.18/version /dependency这段坐标由三部分组成groupId、artifactId、version。你可以理解为一个人的姓、名和身份证号三者组合起来能唯一定位一个jar包。Maven拿到这个坐标会先去本地仓库查找找不到再去远程仓库下载。第二是标准生命周期。Maven把整个构建过程拆成了固定的几个阶段编译、测试、打包、安装、部署。你只需要执行相应命令mvn compile编译Java源码mvn test跑项目里的单元测试mvn package打成jar包或war包mvn install先打包然后把产物安装到本地仓库供其他本地项目引用mvn deploy把产物上传到远程私有仓库这个设计很巧妙团队里所有人执行的都是同样的命令构建流程就标准化了不会再出现“我这边能编译你那边为什么不行”的情况。2. 下载安装版本选择比你想的更讲究2.1 前置条件JDK版本与JAVA_HOME装Maven之前首先要确认机器上已经装了JDK。Maven本身是Java写的工具它运行的前提就是你机器上有可用的Java运行环境。你可以在命令行里先检查java -version如果提示java不是内部或外部命令那说明JDK没装或者环境变量没配置好。这一步卡住的话后面全白搭先把JDK装好再说。JDK版本和Maven版本之间有对应关系不能乱配。Maven 3.9.x系列要求JDK 8以上实测在JDK 8、11、17、21上都能正常运行。但如果你用的是比较老的Maven 3.5.x它和JDK 17以上的版本一起使用时会有兼容性警告有些插件会失效。反过来如果你用的是Maven 4.x新版本虽然也要求JDK 8起步但对新版JDK的支持会更好。我的建议很简单新项目优先用Maven 3.9.xJDK用8或11或17都行。除非你确实需要Maven 4的新特性否则不追新版本。团队协作时Maven版本差异可能带来构建结果不一致的问题统一版本比什么都重要。如果你用的是IDE自带的Maven比如IDEA内置的Maven 3.x那版本基本不用操心。但命令行一定要单独装一份很多自动化脚本、CI流程都依赖命令行Maven。2.2 官网下载二进制包与源码包的区别去Maven官网下载时你会看到页面上一排文件命名大致这样apache-maven-3.9.9-bin.tar.gzapache-maven-3.9.9-bin.zipapache-maven-3.9.9-src.tar.gzapache-maven-3.9.9-src.zip命名里有bin的是编译好的二进制发行包下载这个直接用命名里有src的是源码包需要自己编译普通人用不到。Windows用户直接选apache-maven-3.9.9-bin.zipmacOS或Linux用户选apache-maven-3.9.9-bin.tar.gz。下载完成后解压到一个路径里。这里有一个实际经验解压路径尽量不要带中文和空格。之前遇到过团队新人把Maven解压到D:\工具安装\Maven这种目录后面IDEA配置Maven home时总出莫名其妙的问题。虽然不绝对但带中文路径在某些工具和插件上确实容易出乱子。直接放在D:\apache-maven-3.9.9或者/opt/maven这类纯英文路径下省心很多。2.3 安装目录结构说明解压完之后打开Maven目录你会看到这些子目录bin核心执行脚本mvn命令就在这里boot类加载器相关jar包不用管conf配置文件目录里面最重要的就是settings.xmllibMaven运行依赖的jar包集合这里最容易让新手困惑的就是conf/settings.xml。它是Maven的全局配置文件控制着本地仓库位置、镜像源、代理、服务器认证等一系列行为。后面我会专门用一章讲它。另外注意一点Maven安装目录下的settings.xml是全局级别的配置但它不是唯一的位置。用户目录下的~/.m2/settings.xml优先级更高两个文件都存在时会用用户目录下的那个。这个细节后面细说。3. 环境变量配置与安装验证3.1 Windows环境变量的正确配法安装目录准备好了接下来配置环境变量。Windows上具体步骤如下第一步打开“环境变量”设置界面。可以按Win R输入sysdm.cpl在“高级”选项卡里点“环境变量”或者直接在开始菜单搜“编辑系统环境变量”。第二步在“系统变量”或“用户变量”中新建一个变量。变量名我建议用MAVEN_HOME变量值填Maven的解压路径比如D:\apache-maven-3.9.9。这里有个历史遗留问题老教程都让你配M2_HOME因为当年Maven 2时代用的是这个变量名。现在新版本官方已经不怎么提M2_HOME了但在某些IDEA插件和工具里M2_HOME仍被识别。稳妥起见最不折腾的方式是MAVEN_HOME和M2_HOME两个都配上值都指向同一个目录顶多多花十秒钟能避免很多麻烦。第三步编辑Path变量在末尾追加%MAVEN_HOME%\bin。这里特别提醒Path编辑时一定是追加不是覆盖。新手改环境变量最容易犯的错误就是不小心把原来一长串路径覆盖成自己写的内容结果系统里一堆命令都失效了。点击“新建”加一行%MAVEN_HOME%\bin这种方式最安全。配置完后关键一步把当前已经打开的命令行窗口全部关掉重新开一个新的再执行mvn -v。环境变量只在新的命令行窗口里生效你继续用旧窗口测试永远提示找不到命令。3.2 macOS和Linux环境变量配置macOS和Linux的配置思路一样都是把Maven的bin目录加入PATH。在macOS上如果你用的是bash编辑~/.bash_profile如果用的是zsh新版macOS默认编辑~/.zshrc。在文件末尾加上export MAVEN_HOME/opt/apache-maven-3.9.9 export M2_HOME$MAVEN_HOME export PATH$MAVEN_HOME/bin:$PATH然后执行source ~/.zshrc刷新当前会话。Linux上同理编辑/etc/profile全局所有用户生效或~/.bashrc当前用户生效内容一致。3.3 验证安装mvn -v输出的每个字段含义配置完成后执行mvn -v正常会看到类似这样的输出Apache Maven 3.9.9 (8e4e0e2f9e2e...) Maven home: D:\apache-maven-3.9.9 Java version: 1.8.0_202, vendor: Oracle Corporation Java home: C:\Program Files\Java\jdk1.8.0_202 Default locale: zh_CN, platform encoding: GBK OS name: windows 11, version: 10.0, arch: amd64, family: windows看三个关键信息Maven home是不是你配置的Maven路径。如果这里显示的不是你装的那份说明系统里还装了别的Maven可能是某些IDE或软件自动配到PATH里的。这种干扰最容易导致“明明更新了配置却不生效”的问题。Java version是哪个JDK版本。如果这里显示的还是老版本而你的项目需要JDK 17那就要检查JAVA_HOME指到了哪里。platform encoding当前默认编码。这个字段在Windows上经常是GBK如果你在项目里用了UTF-8编码的源码文件编译时可能会出乱码问题。解决办法是在settings.xml里给maven.compiler.encoding指定UTF-8或者在项目里配置project.build.sourceEncoding。如果执行mvn -v提示mvn不是内部或外部命令基本就是环境变量没生效。按上面的步骤重新排查一次注意新开命令行窗口。4. settings.xml核心配置逐项拆解4.1 全局配置与用户配置到底改哪个这是无数人踩坑的地方。Maven有两个settings.xml全局配置$MAVEN_HOME/conf/settings.xml也就是安装目录下的那个影响这台机器上所有用户。用户配置$HOME/.m2/settings.xmlWindows上就是C:\Users\你的用户名\.m2\settings.xmlLinux和macOS上是~/.m2/settings.xml。.m2目录在你第一次执行Maven命令时才会自动创建。两个文件都存在时会合并生效用户配置覆盖全局配置。也就是说你在~/.m2/settings.xml里配置的镜像地址会覆盖全局配置里的镜像地址。实际项目中我更建议改用户配置不要动安装目录下的全局配置。原因有两个一是因为你换Maven版本时比如从3.9.9升级到4.x直接替换目录就行不用重新迁移自己的个性化配置二是因为用户配置是你个人的不会因为别人借用你的电脑而暴露你的私服账号密码。你只需要把安装目录conf/settings.xml里那份初始文件复制一份到~/.m2/settings.xml然后在用户那份上面改。4.2 localRepository不想把仓库放在C盘的看这里localRepository设置的是本地仓库的位置。Maven下载的所有依赖jar包都存在这个目录下默认是~/.m2/repository。在Windows上这个默认位置在C盘用户目录下。用一段时间后你会发现这个目录疯狂膨胀动辄几个GBC盘空间紧张的话很痛苦。而且一旦系统重装这个目录会整个丢失下次构建又要全部重新下载。建议在安装Maven后第一件事就是改掉本地仓库路径。在settings.xml里把localRepository节点从注释状态打开改成你想要的位置localRepositoryD:\maven-repository/localRepositorymacOS或Linux同理localRepository/data/maven-repository/localRepository注意两点路径不要以/结尾目录名用纯英文不要带中文。同时这个路径不需要提前手动创建Maven会自动生成的。还有一个进阶玩法本地仓库其实是可以跨项目共享的。同一台机器上所有Java项目共享同一个本地仓库不同项目之间的依赖都在这里查。但注意共享的是一个机器上的本地仓库不是多台机器之间的共享。4.3 mirror镜像解决下载慢的根源mirror翻译过来是“镜像”作用是拦截你设置的源然后转到镜像地址去下载。默认情况下Maven从Maven Central中央仓库下载依赖这个仓库架设在国外国内访问速度非常慢甚至直接超时。配置了国内镜像之后依赖下载速度会明显提升。这是settings.xml里最常用、也是最能直接解决“下载慢”问题的配置。具体配置我放到下一章专门讲。先说mirror的工作原理它像一道拦截请求的关卡你可以设置“所有请求都走这个镜像”也可以设置“只让特定仓库的请求走这个镜像”。这个“特定”用mirrorOf节点来控制。4.4 servers与proxy私服认证和网络代理场景servers节点和mirror不一样。mirror只管下载而servers用来存储访问远程仓库时需要的认证信息。实际场景是这样的很多公司内部有私有Maven仓库比如Nexus或Artifactory上传项目产物或者下载私有依赖时这个仓库要求登录认证。你可以在pom.xml里配置distributionManagement指向私服地址然后在settings.xml的servers里配置账号密码servers server idnexus-releases/id usernamedeploy-user/username passwordyour-password/password /server /servers这里有一个关键规则id必须和你的pom.xml里定义的仓库ID完全一致否则Maven匹配不到认证信息上传时会报401认证失败。这个ID的作用就是把服务器地址和账号密码关联起来。proxy节点则用于网络代理场景。如果你的开发环境需要通过公司代理才能访问外网在proxies里配置代理服务器地址proxies proxy idcompany-proxy/id activetrue/active protocolhttp/protocol hostproxy.company.local/host port8080/port nonProxyHostslocalhost|127.0.0.1|*.local/nonProxyHosts /proxy /proxies默认情况下active是true表示生效。如果不需要代理保持默认文件里的注释状态即可。5. 阿里云镜像配置实战5.1 一套稳妥的镜像配置写法国内使用Maven绕不开阿里云镜像。这是作者实测过最稳定的配置方案在settings.xml的mirrors节点下添加如下内容mirrors mirror idaliyunmaven/id namealiyun public/name mirrorOfcentral/mirrorOf urlhttps://maven.aliyun.com/repository/public/url /mirror /mirrors这个https://maven.aliyun.com/repository/public是阿里云的公共聚合仓库里面聚合了Maven Central、JCenter、Google等主流仓库的内容。对国内开发者来说这一个地址基本上就满足开发所需了。如果你用的某些依赖在public里找不到也可以补充其他阿里云仓库地址常用的还有仓库地址用途https://maven.aliyun.com/repository/central只代理Maven Centralhttps://maven.aliyun.com/repository/springSpring相关依赖https://maven.aliyun.com/repository/googleGoogle的Android相关依赖https://maven.aliyun.com/repository/gradle-pluginGradle插件对于一般Java后端项目配一个public就够用了如果项目里混了Android相关依赖建议同时配多个镜像。5.2 mirrorOf的取值陷阱central与*的区别这是很多人配了镜像但没效果、甚至出问题的核心原因。mirrorOf的取值决定这个镜像拦截哪些仓库请求mirrorOfcentral/mirrorOf只拦截Maven Central的请求。意思是只有中央仓库的依赖会走这个镜像私服、第三方仓库都原样访问。这是最推荐的写法。mirrorOf*/mirrorOf拦截所有仓库请求。不管这个依赖来自中央仓库还是其他任何仓库统统走这个镜像。mirrorOfexternal:*/mirrorOf拦截所有对外部仓库的请求但本机地址localhost、file://等除外。实际工作中我看到很多人配了*导致公司私服也被拦到阿里云镜像地址上结果就是公司内部私有依赖下载不到。这个错误排查起来非常隐蔽构建日志里只会出现依赖找不到你不会第一时间想到是镜像配置出了问题。所以我的建议非常明确如果你公司有私有仓库mirrorOf务必写成central如果你完全只用公共仓库、没接触过私服概念用central也绝对够用。没有必要为了省事写*省的事远远没有制造的事多。如果没有配置镜像下载依赖时观察一下命令行输出会有明显区别。配置成功的话下载速度通常能达到几MB每秒不配置从中央仓库直接拉取可能几百KB都算幸运有时候直接卡死在Downloading...那行。6. IDE集成IDEA和VS Code里怎么指定settings.xml6.1 IDEA中的Maven配置很多人在命令行里配好了Maven进了IDEA却发现项目构建依然很慢甚至下载依赖卡死。原因就是IDEA默认使用它自带的Maven而不是你命令行配置的那份也没读取你配置的settings.xml。打开IDEA的File-Settings搜索Maven可以看到三个关键设置项Maven home path这里默认是IDEA内置的Maven你需要点右侧的文件夹图标改成你自己安装的Maven目录比如D:\apache-maven-3.9.9。User settings file这里默认是空的或指向~/.m2/settings.xml。你需要勾选Override然后手动指定你的settings.xml路径。Local repository这里会自动读取settings.xml里的localRepository配置。如果改了settings.xml但Local repository没同步更新点击后面刷新按钮重新读取。这里有个频繁遇到的怪现象改了settings.xml里的镜像配置IDEA里点了刷新依赖下载还是走的旧设置没生效。这时候最有效的操作是点击Maven面板里的Reload All Maven Projects按钮然后再执行mvn clean compile。如果还不行重启一下IDEA。IDEA对配置文件的缓存有时比你想的更顽固。IDEA里还存在一个“当前项目优先”的问题。每个项目在创建时可以选择Maven配置IDEA会把当前项目的.idea/misc.xml或Maven配置单独记录一份。所以如果全局设置改了当前项目还是走的旧配置你需要打开Settings后确认当前Project的级别设置也被同步改了。6.2 VS Code中Maven插件的settings路径设置用VS Code开发Java项目的人越来越多VS Code里用的是Maven for Java这个扩展它默认也算一套独立的Maven配置。热门搜索词里有“vscode maven插件怎么指定settings页面路径”说明这个问题困扰了不少人。步骤是在VS Code里按Ctrl Shift P打开命令面板输入settings打开Open Workspace Settings注意这里要选Workspace还是User要根据你的需求来。然后在设置搜索框里输入maven找到maven.executable.path设置Maven可执行文件的完整路径指向mvn.cmdWindows上或mvnmacOS/Linux上。填到bin目录下就行。maven.settingsFile设置settings.xml的完整路径。maven.terminal.customEnv可以为Maven设置环境变量比如指定JAVA_HOME。手动填路径很容易出错其实VS Code更推荐这样在项目根目录下建一个.vscode/settings.json文件写入{ maven.executable.path: D:/apache-maven-3.9.9/bin/mvn.cmd, maven.settingsFile: C:/Users/你的用户名/.m2/settings.xml }注意JSON里的路径分隔符用正斜杠/反斜杠需要转义或者直接用正斜杠更省事。而且VS Code里配置完这些不会自动生效你需要重新加载窗口或者重启VS Code。7. 高频报错排查我见过的所有翻车现场7.1 构建时卡在下载依赖的解决办法症状执行mvn compile后控制台一直停在Downloading...这行不动运气好的等几分钟有响应运气不好直接报超时错误。这种情况十有八九是镜像没配、或者配了没生效。排查顺序是这样的第一步确认你改对的settings.xml是生效的那份。命令行里执行mvn help:effective-settings这个命令会输出Maven实际生效的所有配置项。如果输出的镜像地址不是你配的那个就说明你改错文件了或者IDEA/VS Code里用的不是这份配置文件。第二步确认镜像URL能直接访问。在浏览器里打开你配置的镜像地址比如https://maven.aliyun.com/repository/public如果能正常打开看到目录列表说明地址没问题如果打不开检查网络。第三步确认依赖坐标没写错。有时候不是下载慢是某个版本号不存在。比如你写的spring-boot-starter-web版本是9.9.9这个版本根本不存在Maven会在各个仓库里反复查找最后报错。可以先在Maven仓库搜索页面比如Central Repository的搜索入口或阿里云仓库的网页里确认一下版本号是否真实存在。7.2 依赖明明存在却提示找不到一种典型情况是你确定某个依赖存在但Maven一直提示Could not resolve dependencies。这很可能是镜像配置范围不对。如果你配了mirrorOf*/mirrorOf所有仓库都被替换成镜像地址。一旦镜像地址里确实没有某个依赖Maven不会回退到原仓库去找而是直接报错。这也是我最推荐central的原因。排查同样的依赖把mirrorOf改成central再构建一次往往问题就消失了。还有一种情况是本地仓库里缓存的元数据或jar包损坏了。比如下载过程中断过一次本地仓库残留了半个jar包文件。解决办法是找到本地仓库里对应的目录把该依赖相关的整个文件夹删掉然后重新构建让Maven重新下载。注意只删出问题的那个依赖目录不要把整个repository目录删了。7.3 改了配置却不生效的检查清单“我改了settings.xml为什么没反应”这个问题我在各种社区里见过的次数太多了。每次排查基本就是过一遍下面这个清单改的是不是生效的那份settings.xml用户配置和全局配置两个文件都存在的场景下用户配置优先。你需要确认自己改的是~/.m2/settings.xml不是安装目录conf/settings.xml那份或者反过来。配置文件格式是否合法settings.xml是XML格式标签关闭错误、多了一个空格、注释没闭合都会导致整个文件无法解析。改完文件后在命令行执行mvn help:effective-settings如果配置格式错误这里会有提示。IDE是否还在用旧配置IDEA和VS Code都有自己的Maven配置项命令行Maven用的是新设置但IDE里可能还在用旧的settings.xml路径。分别在IDE和命令行里各执行一次构建对比一下下载速度就知道差别了。是否重启了终端和IDE环境变量和IDE缓存问题充分重启能解决90%的诡异情况。7.4 一个容易被忽略的JAVA_HOME指向问题最后说一个我见过很多人花很长时间排查的坑。你的机器上可能装了不止一个JDK。比如系统里有Oracle JDK 8也有OpenJDK 17。某些软件的安装过程会把JDK路径写进系统Path里这时候执行java -version显示的可能是JDK 8但mvn -v里显示的Java版本却是另一个。这是因为Maven启动时读取的是JAVA_HOME环境变量而不是Path里的java命令。如果项目要求JDK 11以上但JAVA_HOME指向的是JDK 8那执行Maven构建时很多插件会报错提示Unsupported major.minor version或者Java版本过低。处理方法是把JAVA_HOME显式指向你项目需要的那个JDK根目录然后重启终端验证mvn -v里的Java版本。反过来也有情况Maven用的JDK版本比项目编译目标版本高很多比如项目要求Java 8语法但Maven跑在JDK 17上部分老插件也会不兼容。总之java -version和mvn -v输出不一致就要注意了。最理想的状态是让两个命令指向同一个JDK少很多麻烦。最后再分享一个实操习惯我个人经验里每次在新机器上配置Maven都是固定走这套流程检查JDK、下载Maven二进制包、配环境变量、跑mvn -v验证、复制全局settings.xml到用户目录、改本地仓库路径、配阿里云镜像、mvn help:effective-settings验证生效。整套操作下来十分钟以内能完成但能帮后续项目省下大量等待和排查时间。还有一个值得养成的习惯把settings.xml纳入版本管理。你可以在自己的Git仓库里建一个dotfiles目录专门放这类工具配置文件。换新电脑或者同事入职时直接复制过去改一下路径就能用不用每次都从头回忆“上次加了什么配置”。毕竟配置这种东西一次配置好之后真的是能用很久。这篇文章覆盖了Maven从下载安装到settings.xml核心配置的完整链路。按着里面的步骤走一遍该配的配好该避免的坑避开后面日常开发里Maven这块基本不会给你添堵。