ZetCode

Maven 构建阶段

最后修改于 2025 年 6 月 9 日

在本文中,我们将展示如何理解和使用 Maven 构建阶段和生命周期来进行有效的 Java 项目管理。

什么是 Maven 构建阶段?

Maven 构建阶段是构建生命周期中的各个步骤,它们按照特定顺序执行。每个阶段代表构建过程的一个阶段,从验证项目到部署最终的构件。

阶段与目标(goals)绑定,目标是插件执行的特定任务。当你执行一个阶段时,Maven 会自动运行生命周期中所有先前的阶段,从而确保一个完整且一致的构建过程。

理解阶段对于有效使用 Maven 至关重要,因为它们提供了一种标准化的方法,可以在不同的环境和团队中构建、测试和部署 Java 应用程序。

Maven 构建生命周期

Maven 具有三个内置的构建生命周期,每个生命周期在开发过程中都有不同的目的。

默认生命周期

默认生命周期处理项目部署。它包含了构建和测试应用程序最常用的阶段。

清理生命周期

清理生命周期会移除先前构建生成的构件。它确保在构建项目之前有一个干净的状态。

站点生命周期

站点生命周期生成项目文档和报告。它会创建包含项目信息、测试结果和代码分析的网站。

默认生命周期阶段

默认生命周期包含 23 个阶段,但以下是最重要的,您将经常使用它们:

validate

验证项目是否正确并且所有必需的信息都可用。此阶段会检查 POM 文件结构和必需的属性。

$ mvn validate

compile

编译项目的源代码。编译后的类文件将放置在 target/classes 目录中。

$ mvn compile

test

使用合适的测试框架运行单元测试。在此阶段,测试不会被打包或部署。

$ mvn test

package

获取编译后的代码并将其打包成其可分发格式,例如 JAR 或 WAR 文件。打包后的文件将在 target 目录中创建。

$ mvn package

verify

运行对打包代码的检查,以验证它是否满足质量标准。这可能包括集成测试和代码质量检查。

$ mvn verify

install

将包安装到本地存储库,使其可作为同一台机器上其他项目的依赖项。

$ mvn install

deploy

将最终包复制到远程存储库,以便与其他开发人员和项目共享。这通常在 CI/CD 环境中完成。

$ mvn deploy

阶段执行顺序

当你执行一个特定阶段时,Maven 会自动运行生命周期中的所有先前阶段。这确保了一致性和完整性。

阶段执行示例
# Running package phase executes:
# validate → compile → test → package

$ mvn package

[INFO] --- maven-compiler-plugin:3.11.0:compile (default-compile) ---
[INFO] --- maven-surefire-plugin:3.0.0:test (default-test) ---
[INFO] --- maven-jar-plugin:3.3.0:jar (default-jar) ---

请注意,即使我们只指定了 package,Maven 也自动执行了 compile 和 test 阶段,然后再创建包。

清理生命周期阶段

清理生命周期有三个阶段,有助于维护一个干净的构建环境。

pre-clean

执行实际清理项目之前所需的进程。此阶段很少直接使用,但可以通过插件进行自定义。

clean

删除先前构建生成的所有文件。它会删除 target 目录及其内容。

$ mvn clean

post-clean

执行项目清理之后所需的进程。与 pre-clean 一样,此阶段很少直接使用,但可用于自定义。

组合生命周期

您可以在单个命令中组合来自不同生命周期的阶段。通常这样做是为了确保干净的构建。

$ mvn clean compile    # Clean then compile
$ mvn clean package    # Clean then package
$ mvn clean install    # Clean then install

清理阶段首先运行,然后是默认生命周期中指定的阶段。这确保了先前构建的构件不会干扰当前构建。

跳过阶段

有时您可能希望在开发过程中跳过某些阶段。Maven 提供了用于跳过常见阶段的属性。

跳过测试

跳过测试编译和执行

$ mvn package -DskipTests         # Skip test execution
$ mvn package -Dmaven.test.skip   # Skip test compilation and execution

跳过特定插件

您可以使用特定于插件的属性来跳过特定的插件执行。

$ mvn package -Dcheckstyle.skip   # Skip Checkstyle plugin
$ mvn package -Dpmd.skip          # Skip PMD plugin

阶段绑定示例

让我们来看一下在典型的 Maven 项目中阶段是如何绑定到插件目标的:

pom.xml - 插件绑定
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.11.0</version>
            <executions>
                <execution>
                    <phase>compile</phase>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.0.0</version>
            <executions>
                <execution>
                    <phase>test</phase>
                    <goals>
                        <goal>test</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

此配置显示了 compiler 插件的 compile 目标如何绑定到 compile 阶段,以及 surefire 插件的 test 目标如何绑定到 test 阶段。

自定义阶段执行

您可以将自定义插件目标绑定到特定阶段,以扩展构建过程。

pom.xml - 自定义阶段绑定
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-antrun-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>pre-compile-task</id>
                    <phase>process-sources</phase>
                    <configuration>
                        <target>
                            <echo message="Processing sources before compilation"/>
                        </target>
                    </configuration>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
                
                <execution>
                    <id>post-package-task</id>
                    <phase>package</phase>
                    <configuration>
                        <target>
                            <echo message="Package created successfully"/>
                        </target>
                    </configuration>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

此示例展示了如何使用 AntRun 插件在 process-sourcespackage 阶段执行自定义任务。

查看阶段信息

Maven 提供了一些命令来帮助您理解阶段执行和插件绑定。

$ mvn help:describe -Dcmd=compile    # Describe compile phase
$ mvn help:effective-pom             # Show effective POM
$ mvn help:describe -Dplugin=compiler # Describe compiler plugin

这些命令提供了有关特定阶段期间发生的情况以及如何配置插件的详细信息。

最佳实践

处理 Maven 阶段时,请遵循以下最佳实践:

在进行重要构建之前,请始终运行 mvn clean 以确保干净的状态。对于其他项目可以依赖的完整本地构建,请使用 mvn clean install

在生产构建中避免跳过测试,但在快速开发周期中可以随意跳过它们。在开发过程中,使用 mvn compile 进行快速语法检查。

将自定义目标绑定到适当的阶段,具体取决于它们应该何时执行。预处理任务应绑定到早期阶段,而后处理任务应绑定到后期阶段。

对于包括集成测试在内的全面测试,请使用 mvn verify;如果您只需要构件而不运行集成测试,请使用 mvn package

来源

Maven 生命周期参考

在本文中,我们展示了如何理解和使用 Maven 构建阶段和生命周期来进行有效的 Java 项目管理。

作者

我叫 Jan Bodnar,是一名充满热情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出所有Java教程