Maven 优化技巧

FreeGuideOnline 最新 2026-07-14

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-plugintimestamp-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 参数激活,例如 devprod。将数据库连接、日志配置等环境差异化元素集中在 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