3.5.2. Maven生命周期 (Lifecycle)

上一节中,我们运行的第二个命令是mvn package。命令行并没有指定一个插件目标,而是指定了一个Maven生命周期阶段。一个阶段是在被Maven称为“构建生命周期”中的一个步骤。生命周期是包含在一个项目构建中的一系列有序的阶段。Maven可以支持许多不同的生命周期,但是最常用的生命周期是默认的Maven生命周期,这个生命周期中一开始的一个阶段是验证项目的基本完整性,最后的一个阶段是把一个项目发布成产品。生命周期的阶段被特地留得含糊,单独的定义为验证(validation),测试(testing),或者发布(deployment),而他们对不同项目来说意味着不同的事情。例如,打包(package)这个阶段在一个项目里生成一个JAR,它也就意味着“将一个项目打成一个jar”,而在另外一个项目里,打包这个阶段可能生成一个WAR文件。Figure 3.2, “一个生命周期是一些阶段的序列”展示了默认Maven生命周期的简单样子。

一个生命周期是一些阶段的序列

Figure 3.2. 一个生命周期是一些阶段的序列


插件目标可以附着在生命周期阶段上。随着Maven沿着生命周期的阶段移动,它会执行附着在特定阶段上的目标。每个阶段可能绑定了零个或者多个目标。在之前的小节里,当你运行mvn package,你可能已经注意到了不止一个目标被执行了。检查运行mvn package之后的输出,会注意到那些被运行的各种目标。当这个简单例子到达package阶段的时候,它运行了Jar插件的jar目标。既然我们的简单的quickstart项目(默认)是jar包类型,jar:jar目标被就绑定到了打包阶段。

一个目标绑定到一个阶段

Figure 3.3. 一个目标绑定到一个阶段


我们知道,在包类型为jar的项目中,打包阶段将会创建一个JAR文件。但是,在它之前的目标做什么呢,像compiler:compilesurefire: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文件。

被绑定的目标随着它们阶段的运行而运行

Figure 3.4. 被绑定的目标随着它们阶段的运行而运行


总结得来说,当我们运行mvn package,Maven运行到打包为止的所有阶段,在Maven沿着生命周期一步步向前的过程中,它运行绑定在每个阶段上的所有目标。你也可以像下面这样显式的指定一系列插件目标,以得到同样的结果:

mvn resources:resources \
    compiler:compile \
    resources:testResources \
    compiler:testCompile \
    surefire:test \
    jar:jar

运行package阶段能很好的跟踪一个特定的构建中包含的所有目标,它也允许每个项目使用Maven来遵循一组定义明确的标准。而这个生命周期能让开发人员从一个Maven项目跳到另外一个Maven项目,而不用知道太多每个项目构建的细节。如果你能够构建一个Maven项目,那么你就能构建所有的Maven项目。