5月31日 23:47

Maven 常用命令怎么用?哪些参数能提高构建效率?

Maven 命令看起来很多,其实大部分都围绕三件事:按生命周期构建项目、查看依赖问题、控制构建范围。日常开发不需要背完整手册,但要知道每个命令会跑到哪个阶段、会不会执行测试、会不会把产物写进本地仓库或远程仓库。命令用错,轻则构建慢,重则把不该发布的版本推到仓库。

生命周期命令怎么选?

最常用的是 cleancompiletestpackageinstalldeploy。Maven 会从生命周期起点一直执行到你指定的阶段,所以 mvn package 不只是打包,它会先编译并运行测试;mvn install 会在打包后把产物安装到本地仓库;mvn deploy 则会发布到远程仓库,通常只应由 CI 执行。

bash
mvn 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。

bash
mvn 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 强制检查远程更新。

bash
mvn 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 可以从失败模块继续构建。它们的价值不在“命令高级”,而在少跑无关模块。

bash
mvn 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% 的问题。真正值得记住的不是命令数量,而是每个命令会改变哪些边界:是否清理、是否测试、是否安装、是否发布、是否只构建局部模块。

标签:Maven