上一节中,我们运行的第二个命令是mvn package。命令行并没有指定一个插件目标,而是指定了一个Maven生命周期阶段。一个阶段是在被Maven称为“构建生命周期”中的一个步骤。生命周期是包含在一个项目构建中的一系列有序的阶段。Maven可以支持许多不同的生命周期,但是最常用的生命周期是默认的Maven生命周期,这个生命周期中一开始的一个阶段是验证项目的基本完整性,最后的一个阶段是把一个项目发布成产品。生命周期的阶段被特地留得含糊,单独的定义为验证(validation),测试(testing),或者发布(deployment),而他们对不同项目来说意味着不同的事情。例如,打包(package)这个阶段在一个项目里生成一个JAR,它也就意味着“将一个项目打成一个jar”,而在另外一个项目里,打包这个阶段可能生成一个WAR文件。Figure 3.2, “一个生命周期是一些阶段的序列”展示了默认Maven生命周期的简单样子。
插件目标可以附着在生命周期阶段上。随着Maven沿着生命周期的阶段移动,它会执行附着在特定阶段上的目标。每个阶段可能绑定了零个或者多个目标。在之前的小节里,当你运行mvn
package,你可能已经注意到了不止一个目标被执行了。检查运行mvn
package之后的输出,会注意到那些被运行的各种目标。当这个简单例子到达package
阶段的时候,它运行了Jar插件的jar目标。既然我们的简单的quickstart项目(默认)是jar
包类型,jar:jar
目标被就绑定到了打包阶段。
我们知道,在包类型为jar
的项目中,打包阶段将会创建一个JAR文件。但是,在它之前的目标做什么呢,像compiler:compile
和surefire:test
?在Maven经过它生命周期中package
之前的阶段的时候,这些目标被运行了;Maven执行一个阶段的时候,它首先会有序的执行前面的所有阶段,到命令行指定的那个阶段为止。每个阶段对应了零个或者多个目标。我们没有进行任何插件配置或者定制,所以这个例子绑定了一组标准插件的目标到默认的生命周期。当Maven经过以package
为结尾的默认生命周期的时候,下面的目标按顺序被执行:
resources:resources
-
Resources插件的
resources
目标绑定到了resources
阶段。这个目标复制src/main/resources
下的所有资源和其它任何配置的资源目录,到输出目录。 compiler:compile
-
Compiler插件的
compile
目标绑定到了compile
阶段。这个目标编译src/main/java
下的所有源代码和其他任何配置的资源目录,到输出目录。 resources:testResources
-
Resources插件的
testResources
目标绑定到了test-resources
阶段。这个目标复制src/test/resources
下的所有资源和其它任何的配置的测试资源目录,到测试输出目录。 compiler:testCompile
-
Compiler插件的
testCompile
目标绑定到了test-compile
阶段。这个目标编译src/test/java
下的测试用例和其它任何的配置的测试资源目录,到测试输出目录。 surefire:test
-
Surefire插件的
test
目标绑定到了test
阶段。这个目标运行所有的测试并且创建那些捕捉详细测试结果的输出文件。默认情况下,如果有测试失败,这个目标会终止。 jar:jar
-
Jar插件的
jar
目标绑定到了package
阶段。这个目标把输出目录打包成JAR文件。
总结得来说,当我们运行mvn package,Maven运行到打包为止的所有阶段,在Maven沿着生命周期一步步向前的过程中,它运行绑定在每个阶段上的所有目标。你也可以像下面这样显式的指定一系列插件目标,以得到同样的结果:
mvn resources:resources \
compiler:compile \
resources:testResources \
compiler:testCompile \
surefire:test \
jar:jar
运行package
阶段能很好的跟踪一个特定的构建中包含的所有目标,它也允许每个项目使用Maven来遵循一组定义明确的标准。而这个生命周期能让开发人员从一个Maven项目跳到另外一个Maven项目,而不用知道太多每个项目构建的细节。如果你能够构建一个Maven项目,那么你就能构建所有的Maven项目。