Maven 优化技巧
xml org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-tomcat
### 1.2 使用 dependency:analyze 发现无用依赖
执行以下命令,Maven 会列出声明了但未实际使用的依赖(Unused declared dependencies),以及直接使用但未声明的依赖(Used undeclared dependencies)。这能帮你清理无效的 `<dependency>` 条目。
```bash
mvn dependency:analyze
提示:命令只会分析编译期引用,反射加载的类可能被误报,需人工复核。
1.3 统一版本管理
项目多模块时,必须用 <dependencyManagement> 统一定义版本号,子模块只需写坐标,无需版本。这不仅保证一致性,还便于批量升级。
<!-- parent pom.xml -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>33.0.0-jre</version>
</dependency>
</dependencies>
</dependencyManagement>
1.4 善用 scope 减少传递范围
合理设置依赖的 <scope>,避免 JAR 包被泄露到不需要的环境。例如测试相关的库应设为 test,提供编译时 API 但运行时由容器提供的库应设为 provided。
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
2 插件配置优化:让构建更高效
2.1 跳过无意义的插件执行
很多插件默认会在每个生命周期阶段执行,但实际上某些步骤可以跳过。例如对纯父 POM 或 BOM 项目,无需执行 maven-jar-plugin 的打包。
<!-- 父 POM 中跳过 jar 打包和 install -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>default-jar</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
2.2 并行执行插件
Maven 默认串行运行模块构建,我们可以通过 -T 参数启用多线程构建。如果你的插件不涉及操作共享资源(如端口绑定),可以安全地使用:
mvn clean install -T 4
其中 4 表示使用 4 个线程。对于 CI 环境,推荐 -T 1C,按 CPU 核心数自动分配。
2.3 优化 maven-compiler-plugin
编译器本身的速度直接影响构建时间。建议显式配置 <release> (Java 9+)或 <source>/<target>,避免使用默认值。还可启用增量编译(但注意增量编译在复杂多模块场景可能有不稳定情况)。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<release>17</release>
<compilerArgs>
<!-- 开启额外警告 -->
<arg>-Xlint:all</arg>
</compilerArgs>
</configuration>
</plugin>
2.4 使用 maven-resources-plugin 的正确姿势
资源文件的复制若配置了过滤(filtering=true),尤其是包含大量占位符替换时,会拖慢构建。若非必要,关掉过滤。对于大型静态资源目录,可考虑使用 excludes 排除不需要的文件。
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
</resource>
</resources>
3 仓库与镜像:下载依赖的速度革命
3.1 配置国内镜像
在中国大陆开发者通常需要替换中央仓库为阿里云镜像,否则下载速度极低。在 ~/.m2/settings.xml 中添加:
<mirrors>
<mirror>
<id>aliyunmaven</id>
<mirrorOf>central</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
3.2 使用私有仓库缓存依赖
企业团队应搭建 Nexus 或 Artifactory 私有仓库,作为所有远程仓库的代理。这样内部构建速度会大幅提升,且能统一管控依赖安全。
3.3 减少不必要的仓库声明
每个仓库的 <repository> 声明都会让 Maven 在下载依赖时依次查询,特别是 <snapshots> 仓库的检查开销较大。请删除不再使用的仓库配置,并在 settings.xml 中全局禁用 SNAPSHOT 仓库的自动更新:
<profiles>
<profile>
<id>disable-snapshot-search</id>
<repositories>
<repository>
<id>central</id>
<url>https://repo.maven.apache.org/maven2</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>disable-snapshot-search</activeProfile>
</activeProfiles>
4 命令与执行:小技巧大作用
4.1 离线构建
当所有依赖已下载到本地仓库,可以使用 -o 参数完全脱机构建,避免任何网络检查。
mvn clean package -o
4.2 跳过测试
开发阶段快速验证编译和打包时,可以通过命令跳过测试执行,甚至跳过测试编译。
- 跳过测试运行:
-DskipTests - 连测试代码都不编译:
-Dmaven.test.skip=true
mvn package -Dmaven.test.skip=true
4.3 只构建需要的模块
大型多模块项目,若只修改了其中一个模块,不需要全量构建。可使用 -pl 指定模块,配合 -am (also-make) 自动包含修改模块的依赖模块。
mvn clean install -pl my-module -am
4.4 分析构建耗时
使用 maven-buildtime-extension 或直接使用 build-helper-maven-plugin 的 timestamp-property 功能来定位耗时最长的插件。更推荐 Maven 3.9.1+ 自带的时间日志:在执行命令时添加 -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=debug,但更简单的办法是使用专门的分析扩展。
5 配置文件瘦身与复用
5.1 善用 <parent> 继承
将公共配置(插件版本、属性、仓库、build 配置)提升到父 POM,子模块只保留必要的差异部分,可极大降低维护成本。
5.2 使用 profiles 分离环境
在 settings.xml 或父 POM 中定义不同环境的 profile,通过 -P 参数激活,例如 dev、prod。将数据库连接、日志配置等环境差异化元素集中在 profile 中。
<profiles>
<profile>
<id>dev</id>
<properties>
<env>development</env>
</properties>
</profile>
</profiles>
5.3 Maven Wrapper 统一版本
在项目根目录执行 mvn wrapper:wrapper 生成 .mvn/wrapper/maven-wrapper.properties,锁定 Maven 版本。所有开发者使用 ./mvnw 代替 mvn 命令,无需担心本地 Maven 版本差异。
6 高级优化:构建缓存与增量编译
6.1 使用 Maven Daemon
mvnd 是 Maven 官方推出的守护进程,可预加载 JVM 和 Maven 核心,显著缩短启动时间。安装后直接用 mvnd 代替 mvn 命令,其他参数完全兼容。
mvnd clean install -T 4