Maven 常用命令怎么用?哪些参数能提高构建效率?
Maven 命令看起来很多,其实大部分都围绕三件事:按生命周期构建项目、查看依赖问题、控制构建范围。日常开发不需要背完整手册,但要知道每个命令会跑到哪个阶段、会不会执行测试、会不会把产物写进本地仓库或远程仓库。命令用错,轻则构建慢,重则把不该发布的版本推到仓库。
生命周期命令怎么选?
最常用的是 clean、compile、test、package、install 和 deploy。Maven 会从生命周期起点一直执行到你指定的阶段,所以 mvn package 不只是打包,它会先编译并运行测试;mvn install 会在打包后把产物安装到本地仓库;mvn deploy 则会发布到远程仓库,通常只应由 CI 执行。
bashmvn clean # 删除 target 目录 mvn compile # 编译主代码 mvn test # 运行单元测试 mvn package # 生成 jar/war mvn install # 安装到本地仓库 mvn deploy # 发布到远程仓库
开发阶段想快速验证语法和依赖,mvn test 往往比 clean install 更合适。clean install 很完整,但它会清理增量结果并写入本地仓库,在大项目中成本不低。只有需要验证全量构建、给其他本地模块引用产物,或 CI 做最终检查时,才更适合用它。
依赖排查命令怎么用?
依赖冲突、版本不一致、包重复,是 Maven 项目里最常见的构建问题。dependency:tree 用来查看依赖来源,dependency:analyze 用来发现声明了但没用、用了却没声明的依赖。前者适合排查版本冲突,后者适合清理 POM。
bashmvn dependency:tree mvn dependency:tree -Dincludes=com.fasterxml.jackson.core mvn dependency:analyze mvn dependency:resolve mvn dependency:sources
如果本地依赖损坏,可以用 dependency:purge-local-repository 清理后重新下载,但不要把它当成日常加速手段。它会让下一次构建重新拉依赖,网络慢时反而更耗时。遇到 SNAPSHOT 依赖没更新,可以加 -U 强制检查远程更新。
bashmvn clean test -Dtest=OrderServiceTest mvn test -DfailIfNoTests=false mvn help:effective-pom mvn help:active-profiles
定位问题时,help:effective-pom 很有用。它会把父 POM、当前 POM、Profile 和默认配置合并后展示出来,比直接盯着一个 pom.xml 更接近 Maven 实际看到的内容。边界是输出很长,适合排查“配置到底从哪来”,不适合每次构建都跑。
多模块项目怎么少构建一点?
多模块工程最有用的参数是 -pl、-am 和 -rf。-pl 指定构建哪些模块,-am 会顺带构建这些模块依赖的上游模块,-rf 可以从失败模块继续构建。它们的价值不在“命令高级”,而在少跑无关模块。
bashmvn test -pl order-service -am mvn package -pl '!legacy-module' mvn install -rf payment-service mvn clean install -T 1C
-T 可以并行构建,例如 -T 1C 表示每个 CPU 核心一个线程。边界是并行只对模块间依赖清楚、插件线程安全的项目效果好。如果某些插件会写同一个文件,或者测试依赖共享端口,并行构建可能把偶发失败放大。
追问
-DskipTests 和 -Dmaven.test.skip=true 有什么区别?
-DskipTests 会跳过测试执行,但通常仍会编译测试代码。-Dmaven.test.skip=true 会跳过测试编译和测试执行,速度更快,但也更容易掩盖测试代码编译失败。日常临时打包可以用前者,CI 主流程不建议长期跳测试。踩坑点是测试工具类被主代码误引用时,跳过测试编译可能让问题延后暴露。
什么时候用 mvn install,什么时候只用 mvn package?
如果只是看当前项目能不能打包,package 就够了。install 会把产物写入 ~/.m2/repository,适合本地另一个项目要引用这个 SNAPSHOT 包的场景。它的副作用是本地仓库可能残留旧快照,让你误以为代码已经同步。多人协作时,真正共享的版本应该走远程仓库,而不是靠各自本地 install。
为什么 dependency:tree 查到了冲突,运行时还是报错?
dependency:tree 只能告诉你 Maven 解析出的依赖路径,不保证运行环境和它完全一致。应用服务器、自带 lib、Spring Boot 打包插件、shade 插件都可能改变最终 classpath。排查时要结合最终包内容,例如查看 BOOT-INF/lib 或运行时启动日志。边界是:构建期依赖正确,不等于部署形态一定正确。
-o 离线模式适合所有场景吗?
不适合。mvn -o 只使用本地仓库,网络不可用或 CI 缓存充分时很有用。它的前提是所有依赖、插件和父 POM 都已经存在本地,否则构建会直接失败。常见踩坑是只缓存了依赖,没缓存插件,结果离线构建卡在插件解析。
命令参数写得越多越专业吗?
不是。参数越多,构建语义越难复现,尤其是 -D 覆盖属性、-P 激活 profile、跳过插件这些参数。团队里最好把稳定规则写进 POM 或 CI 脚本,把临时参数留给本地排查。否则同一个项目会出现“我的命令能过、你的命令不过”的情况。
把 Maven 命令分成构建、依赖排查、多模块加速三类,基本就能覆盖日常 80% 的问题。真正值得记住的不是命令数量,而是每个命令会改变哪些边界:是否清理、是否测试、是否安装、是否发布、是否只构建局部模块。