Maven目标和阶段之间的区别/关系是什么?它们之间有什么关系?


目标是分阶段执行的,这有助于确定目标执行的顺序。最好的理解方法是查看默认的Maven生命周期绑定,该绑定显示默认情况下哪个目标在哪个阶段运行。编译阶段目标总是在测试阶段目标之前执行,测试阶段目标总是在包阶段目标之前执行,以此类推。

执行Maven时可以指定目标或阶段,这在一定程度上加剧了这种混乱。如果您指定了一个阶段,那么Maven将运行所有阶段,直到您指定的阶段(例如,如果您指定了包,它将首先运行编译阶段,然后是测试阶段,最后是包阶段),并且对于每个阶段,它将运行与该阶段相关的所有目标。

当您在Maven构建文件中创建插件执行时,如果您只指定了目标,那么它就会将该目标绑定到给定的默认阶段。例如,jaxb:xjc目标默认绑定到生成资源阶段。但是,当您指定执行时,您还可以显式地指定该目标的阶段。

如果您在执行Maven时指定了一个目标,那么它将运行该目标,且仅运行该目标。换句话说,如果您指定了jar:jar目标,它将只运行jar:jar目标来将您的代码打包到一个jar中。如果您之前没有运行编译目标或以其他方式准备编译后的代码,则很可能会失败。


具有阶段和目标的Maven工作术语。

阶段:Maven阶段是一组与2或3个目标相关的行动

示例:-如果您运行MVN清洁

这是MVN阶段要执行的清洁目标:清洁

目标:与阶段有界限的Maven目标

供参考 http://books.sonatype.com/mvnref-book/reference/lifecycle-sect-structure.html


这些定义在Maven站点的构建生命周期介绍页面中有详细说明,但是我已经尝试总结:

Maven定义了构建过程的4项:

Lifecycle Three built-in lifecycles (aka build lifecycles): default, clean, site. (Lifecycle Reference) Phase Each lifecycle is made up of phases, e.g. for the default lifecycle: compile, test, package, install, etc. Plugin An artifact that provides one or more goals. Based on packaging type (jar, war, etc.) plugins' goals are bound to phases by default. (Built-in Lifecycle Bindings) Goal The task (action) that is executed. A plugin can have one or more goals. One or more goals need to be specified when configuring a plugin in a POM. Additionally, in case a plugin does not have a default phase defined, the specified goal(s) can be bound to a phase.

Maven可以通过以下方式调用:

阶段(如清洁、打包) <plugin-prefix>:<goal>(例如:copy-dependencies) <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>(例如:org.apache.maven.plugins:maven-compiler-plugin:3.7.0:compile)

混合的:任意或全部的一个或多个组合,例如:

mvn clean dependency:copy-dependencies package

选择的答案很好,但我仍然想为这个话题补充一些小的东西。一个例证。

它清楚地展示了不同的阶段如何绑定到不同的插件以及这些插件暴露的目标。

所以,让我们检查一个运行类似mvn compile的例子:

这是一个执行编译器插件的阶段 编译的目标 编译器插件有不同的目标。对于mvn编译,它被映射到一个特定的目标,编译目标。 这与运行mvn编译器:compile相同

因此,阶段是由插件目标组成的。

链接到参考资料


生命周期是一系列已命名的阶段。 phase按顺序执行。执行一个阶段意味着执行之前的所有阶段。

插件是目标的集合(例如:任务),也称为MOJO (Maven旧Java对象)。

Maven基于构建生命周期的核心概念。在每个构建生命周期中都有构建阶段,在每个构建阶段中都有构建目标。

我们可以执行构建阶段或构建目标。当执行一个构建阶段时,我们执行该构建阶段中的所有构建目标。构建目标被分配到一个或多个构建阶段。我们也可以直接执行一个构建目标。

有三个主要的内置构建生命周期:

默认的 清洁 网站

每个构建生命周期都由阶段组成

例如,默认的生命周期由以下构建阶段组成:

◾validate - validate the project is correct and all necessary information is available
◾compile - compile the source code of the project
◾test - test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed
◾package - take the compiled code and package it in its distributable format, such as a JAR.
◾integration-test - process and deploy the package if necessary into an environment where integration tests can be run
◾verify - run any checks to verify the package is valid and meets quality criteria
◾install - install the package into the local repository, for use as a dependency in other projects locally
◾deploy - done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects.

为了完成以上阶段,我们只需要调用一个命令:

mvn <phase> { Ex: mvn install }

对于上述命令,从第一阶段开始,依次执行所有阶段,直到“安装”阶段。MVN可以执行一个目标或一个阶段(甚至多个目标或多个阶段),如下所示:

mvn clean install plugin:goal  

但是,如果你想自定义引用插件的前缀,你可以直接通过插件POM中的maven-plugin-plugin的配置参数指定前缀。

构建阶段由插件目标组成

Maven的大部分功能都在插件中。插件提供了一组目标,可以使用以下语法执行:

 mvn [plugin-name]:[goal-name]

例如,一个Java项目可以通过运行mvn compiler:compile来使用compiler-plugin的编译目标进行编译。

构建生命周期是一个已命名阶段的列表,可用于为目标执行提供顺序。

插件提供的目标可以与生命周期的不同阶段相关联。例如,默认情况下,目标compiler:compile与compile阶段相关联,而目标surefire:test与测试阶段相关联。考虑以下命令:

mvn test

当执行上面的命令时,Maven将运行与测试阶段之前和包括测试阶段在内的每个阶段相关的所有目标。在这种情况下,Maven运行与流程-资源阶段相关联的资源:资源目标,然后是编译器:编译,以此类推,直到最后运行surefire:测试目标。

然而,即使构建阶段负责构建生命周期中的特定步骤,它执行这些职责的方式也可能不同。这是通过声明与这些构建阶段绑定的插件目标来实现的。

A plugin goal represents a specific task (finer than a build phase) which contributes to the building and managing of a project. It may be bound to zero or more build phases. A goal not bound to any build phase could be executed outside of the build lifecycle by direct invocation. The order of execution depends on the order in which the goal(s) and the build phase(s) are invoked. For example, consider the command below. The clean and package arguments are build phases, while the dependency:copy-dependencies is a goal (of a plugin).

mvn clean dependency:copy-dependencies package

如果要执行这个,那么将首先执行清洁阶段(意味着它将运行清洁生命周期的所有前面阶段,加上清洁阶段本身),然后是依赖项:复制依赖项目标,最后执行包阶段(以及默认生命周期的所有前面构建阶段)。

此外,如果一个目标被绑定到一个或多个构建阶段,那么该目标将在所有这些阶段中被调用。

此外,构建阶段也可以有零个或多个目标。如果构建阶段没有与之绑定的目标,那么该构建阶段将不会执行。但如果它有一个或多个目标,它就会执行所有这些目标。

内置生命周期绑定 有些阶段默认有目标。对于默认的生命周期,这些绑定取决于打包值。

Maven架构:

参考1 参考2

Maven生命周期映射的Eclipse示例


归功于Sandeep Jindal和Premraj。我一时糊涂,他们的解释让我明白了。

我在这里创建了一些完整的代码示例和一些简单的解释https://www.surasint.com/maven-life-cycle-phase-and-goal-easy-explained/。我想这可以帮助别人理解。

简而言之,你不应该试图一次理解所有这三个组,首先你应该理解这三个组之间的关系:

生命周期vs阶段 插件vs目标

1. 生命周期vs阶段

生命周期是按顺序的阶段的集合,请参阅这里的生命周期参考。当你调用一个相位时,它也会调用它之前的所有相位。

例如,清洁生命周期有3个阶段(清洁前、清洁后)。

mvn clean

它会调用pre-clean和clean。

2. 插件vs目标

目标就像Plugin中的一个动作。如果plugin是一个类,goal是一个方法。

你可以这样称呼一个进球:

mvn clean:clean

这意味着“在清洁插件中调用清洁目标”(这里与清洁阶段无关。不要让“干净”这个词混淆了你,它们不是一样的!)

3.现在,阶段和目标之间的关系:

阶段可以(预)链接到目标。例如,通常,清洁阶段与清洁目标相关联。所以,当你调用这个命令时:

mvn clean

它将调用预清洁阶段和清洁阶段,后者与清洁目标相关联。

它几乎等同于:

mvn pre-clean clean:clean

更多细节和完整的例子见https://www.surasint.com/maven-life-cycle-phase-and-goal-easy-explained/


有以下三个内置的构建生命周期:

默认的 清洁 网站

生命周期默认值->[验证、初始化、生成源、流程源、生成资源、流程资源、编译、流程类、生成测试源、流程测试源、生成测试资源、流程测试资源、测试编译、流程测试类、测试、准备包、包、预集成测试、集成测试、后集成测试、验证、安装、部署]

生命周期清洁->[预清洁,清洁,后清洁]

生命周期站点->[站点前,站点,站点后,站点部署]

流是顺序的,例如,对于默认的生命周期,它从验证开始,然后初始化等等…

您可以通过启用mvn的调试模式来检查生命周期,即mvn -X <your_goal>


我相信已经提供了一个很好的答案,但我想添加一个易于理解的图,说明不同的3个生命周期(构建、清洁和站点)以及每个生命周期的阶段。

粗体的相位是常用的主要相位。


关于佩斯的回答,

如果您在执行Maven时指定了一个目标,那么它将运行该目标,且仅运行该目标。换句话说,如果您指定了jar:jar目标,它将只运行jar:jar目标来将您的代码打包到一个jar中。

这种说法有一个例外。Maven插件API允许目标触发生命周期阶段的执行。

考虑以下项目:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.example</groupId>
  <artifactId>simple-maven-project</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
</project>

当你执行spring-boot-maven-plugin中定义的目标运行时

mvn org.springframework.boot:spring-boot-maven-plugin:run

它打印

[INFO] ------------------< org.example:simple-maven-project >------------------
[INFO] Building simple-maven-project 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] >>> spring-boot-maven-plugin:3.0.0:run (default-cli) > test-compile @ simple-maven-project >>>
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ simple-maven-project ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory C:\Users\Bartosz\IdeaProjects\simple-maven-project\src\main\resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ simple-maven-project ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ simple-maven-project ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory C:\Users\Bartosz\IdeaProjects\simple-maven-project\src\test\resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ simple-maven-project ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] <<< spring-boot-maven-plugin:3.0.0:run (default-cli) < test-compile @ simple-maven-project <<<
[INFO] 
[INFO] 
[INFO] --- spring-boot-maven-plugin:3.0.0:run (default-cli) @ simple-maven-project ---
[INFO] ------------------------------------------------------------------------

这是因为spring-boot-maven-plugin-X.X.X.jar/META-INF/maven/plugin.xml中的目标定义包含<executePhase>test-compile</executePhase>,它执行test-compile和所有前面的阶段。

<mojo>
    <goal>run</goal>
    (...)
    <executePhase>test-compile</executePhase>
    (...)
</mojo>

此外,由于“jar”打包的默认绑定,很少执行其他目标。如果将打包更改为“pom”,则相同的命令将生成

[INFO] ------------------< org.example:simple-maven-project >------------------
[INFO] Building simple-maven-project 1.0-SNAPSHOT
[INFO] --------------------------------[ pom ]---------------------------------
[INFO] 
[INFO] >>> spring-boot-maven-plugin:3.0.0:run (default-cli) > test-compile @ simple-maven-project >>>
[INFO] 
[INFO] <<< spring-boot-maven-plugin:3.0.0:run (default-cli) < test-compile @ simple-maven-project <<<
[INFO] 
[INFO] 
[INFO] --- spring-boot-maven-plugin:3.0.0:run (default-cli) @ simple-maven-project ---
[INFO] ------------------------------------------------------------------------

因为对于test-compile或任何之前的阶段和此打包类型没有默认绑定。