生命周期
提到Maven插件,就不得不理解maven的生命周期。 因为Maven的生命周期是抽象的(提供一致统一的构建标准),各个阶段都是靠插件来完成的。 Maven有三套生命周期, clean生命周期, default生命周期(构建), site生命周期。 每套生命周期又包含多个阶段(phase), 不同生命周期是相互独立的。
三套生命周期
clean生命周期
clean生命周期的目的是清理项目。包含如下阶段:
- pre-clean:清理前
- clean:清理
- post-clean:清理后
default生命周期
default生命周期定义了真正构建时所需要执行的所有步骤,是最核心的部分。
简化的理解就是:
- 编译前的处理
- 编译(compile)
- 测试(test)
- 打包(prepare-package和package)
- 安装(install)
- 上传发布(deploy)
具体它包含如下阶段(摘自官网):
Phase | Description |
---|---|
validate | validate the project is correct and all necessary information is available. |
initialize | initialize build state, e.g. set properties or create directories. |
generate-sources | generate any source code for inclusion in compilation. |
process-sources | process the source code, for example to filter any values. |
generate-resources | generate resources for inclusion in the package. |
process-resources | copy and process the resources into the destination directory, ready for packaging. |
compile | compile the source code of the project. |
process-classes | post-process the generated files from compilation, for example to do bytecode enhancement on Java classes. |
generate-test-sources | generate any test source code for inclusion in compilation. |
process-test-sources | process the test source code, for example to filter any values. |
generate-test-resources | create resources for testing. |
process-test-resources | copy and process the resources into the test destination directory. |
test-compile | compile the test source code into the test destination directory |
process-test-classes | post-process the generated files from test compilation, for example to do bytecode enhancement on Java classes. For Maven 2.0.5 and above. |
test | run tests using a suitable unit testing framework. These tests should not require the code be packaged or deployed. |
prepare-package | perform any operations necessary to prepare a package before the actual packaging. This often results in an unpacked, processed version of the package. (Maven 2.1 and above) |
package | take the compiled code and package it in its distributable format, such as a JAR. |
pre-integration-test | perform actions required before integration tests are executed. This may involve things such as setting up the required environment. |
integration-test | process and deploy the package if necessary into an environment where integration tests can be run. |
post-integration-test | perform actions required after integration tests have been executed. This may including cleaning up the environment. |
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. |
site生命周期
site生命周期的目的是建立和发布项目站点, 基于pom所包含的信息,生成一个友好站点。包含如下阶段:
- pre-site:生成项目站点前
- site:生成项目站点
- post-site:生成的项目站点后
- site-deploy:生成的项目站点发布到服务器
生命周期的关系
执行Maven任务最主要的方式就是调用Maven的生命周期,各套生命周期之间是相互独立的, 而每套生命周期内的阶段则是前后依赖的关系。 例如:
mvn clean
调用的是clean生命周期的 pre-clean和clean阶段mvn compile
调用default生命周期的 validate,initialize等直到compile阶段mvn clean compile
则分别调用 clean生命周期的pre-clean和clean阶段,以及default生命周期的 validate直到compile的阶段。
插件目标的理解
- 一个插件可能有多个目标。 如果将插件比作类, 那么插件目标则是类对外提供的公共方法(接口)。
- 为了复用代码如私有成员或方法,把几个接口放到同一个类中。
- 那么,要调用接口, 则要指明是哪个包哪个类的哪个接口哪个签名。 当然, 在写接口时,有可能已经指定了调用这个类没有指定时用哪个接口 (默认指定)。
- 插件也是一样,为了复用代码,也可能会有几个目标以及绑定默认目标。
- 因此,显式调用插件时, 也需要指明插件坐标和目标。
groupId:artifactId:version:goal
- 如调用编译插件编译源码,完整的为:
mvn org.apache.maven.plugins:maven-compiler-plugin:3.1:compile
插件目标与生命周期绑定
- 除了上面显式用Maven调用插件目标,大部分情况,我们是直接运行Maven的生命周期阶段的。Maven的生命周期是与插件的目标相互绑定的。
- 例如,插件
maven-compiler-plugin
的compile
目标能够完成编译的任务,mvn compile
与这个目标相绑定 , 就实现了编译的目的。 - 那么,
mvn compile
与mvn org.apache.maven.plugins:maven-compiler-plugin:3.1:compile
的作用是类似的- 一个是调用maven的default生命周期的compile阶段(会执行前面的阶段)
- 一个是显式执行maven-compiler-plugin插件的compile目标。
内置绑定
- 而之所以
mvn compile
会自动调用mvn org.apache.maven.plugins:maven-compiler-plugin:3.1:compile
是因为Maven内置绑定了这个插件目标。- 即执行到compile阶段,就会调用这个目标。
- 具体有那些内置绑定可以查看Maven官方说明:
生命周期与内置绑定
default生命周期阶段的内置绑定对照
自定义绑定
但是有些阶段没有绑定目标或者我们需要执行额外的目标, 那么可以自己另外绑定目标,绑定到同一个阶段的插件目标都会执行。例如,生成源码的jar包,如下
<build>
<plugins>
<plugin>
<!-- 插件坐标,groupId是org.apache.maven.plugins可以省略 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.1</version>
<!-- 只定义不指定执行参数如绑定的生命周期等,那么调用到生命周期时不会执行(插件默认绑定生命周期的例外)-->
<executions>
<!-- 可以有多个绑定 -->
<execution>
<!-- 执行id,可以随便取。在执行时控制台会显示 -->
<id>attach-sources</id>
<!-- 默认绑定 verify -->
<phase>compile</phase>
<!-- 可以执行多个目标 -->
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
具体执行了哪些生命周期和目标,我们在控制台是可以看到的。如图,使用mvn clean compile