浅谈Maven构建过程
本文参考Maven官方文档编写[1]。
1. 背景
作为Maven的使用者,我们可以通过mvn clean install
命令进行Maven项目的清理和打包;可以通过mvn dependency:tree
命令输出Maven项目的依赖列表;也可以通过mvn -h
命令查看mvn
命令的用法:
> mvn -h
> usage: mvn [options] [<goal(s)>] [<phase(s)>]
Maven作为一个构建工具,对项目的构建过程进行了抽象,派生出了以下几个概念:
- 构建生命周期(Build Lifecycles)
- 构建阶段(Build Phases)
- 插件目标(Plugin Goals)
了解这些概念能够更好地掌握Maven的构建过程以及为Maven插件的使用与开发提供支持。
2. 构建生命周期
Maven提供了三种内置的构建生命周期[1],下文简称生命周期。分别是:
default
:处理项目的部署。clean
:负责项目的清理。site
:负责项目web站点的创建。
3. 构建阶段
每个生命周期由多个构建阶段[1]组成。例如,default
生命周期包括以下几个构建阶段(完整的构建阶段见附录):
validate
:验证项目是否正确且所有必要的信息是否可用。compile
:编译项目的源代码。test
:使用单元测试框架测试编译后的源代码。package
:收集编译后的源代码并打包为可分发的格式,如JAR。verify
:对集成测试的结果进行检查,以确保其满足质量标准。install
:安装包到本地仓库,使其可以作为其他本地项目的依赖项。deploy
:复制最终的包到远程仓库,使其可以作为其他项目的依赖项。
当执行生命周期的某个构建阶段时,会按该生命周期中的构建阶段顺序执行该阶段前的其他构建阶段。如当执行mvn clean install
时,会依次执行:
clean
生命周期的pre-clean
,clean
构建阶段;default
生命周期的validate
,compile
,test
,package
,verify
,install
构建阶段。
4. 插件目标
每个构建阶段由零个或多个插件目标[1]组成。生命周期和构建阶段是逻辑上的概念,插件目标才是可执行的具体任务。
- 每个插件可以声明多个插件目标,每个插件目标可以绑定多个构建阶段。
- 每个构建阶段可以被零个或多个插件目标绑定。
- 插件目标除了可以绑定构建阶段外,也可以单独执行(如上文提到的
mvn dependency:tree
)。
以打包方式为JAR的Maven项目为例,default
生命周期所对应的插件目标与构建阶段的默认绑定关系如下配置[6]:
<!-- https://github.com/apache/maven/blob/maven-3.9.9/maven-core/src/main/resources/META-INF/plexus/default-bindings.xml -->
<!--
| JAR
|-->
<component>
<role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
<role-hint>jar</role-hint>
<implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
<configuration>
<lifecycles>
<lifecycle>
<id>default</id>
<!-- START SNIPPET: jar-lifecycle -->
<phases>
<process-resources>
org.apache.maven.plugins:maven-resources-plugin:3.3.1:resources
</process-resources>
<compile>
org.apache.maven.plugins:maven-compiler-plugin:3.13.0:compile
</compile>
<process-test-resources>
org.apache.maven.plugins:maven-resources-plugin:3.3.1:testResources
</process-test-resources>
<test-compile>
org.apache.maven.plugins:maven-compiler-plugin:3.13.0:testCompile
</test-compile>
<test>
org.apache.maven.plugins:maven-surefire-plugin:3.2.5:test
</test>
<package>
org.apache.maven.plugins:maven-jar-plugin:3.4.1:jar
</package>
<install>
org.apache.maven.plugins:maven-install-plugin:3.1.2:install
</install>
<deploy>
org.apache.maven.plugins:maven-deploy-plugin:3.1.2:deploy
</deploy>
</phases>
<!-- END SNIPPET: jar-lifecycle -->
</lifecycle>
</lifecycles>
</configuration>
</component>
从配置文件中可以看到default
生命周期的:
compile
构建阶段被插件目标org.apache.maven.plugins:maven-compiler-plugin:3.13.0:compile
绑定 。插件:
org.apache.maven.plugins:maven-compiler-plugin:3.13.0
。目标:
compile
。
install
构建阶段被插件目标org.apache.maven.plugins:maven-install-plugin:3.1.2:install
绑定。- 插件:
org.apache.maven.plugins:maven-install-plugin:3.1.2
。 - 目标:
install
。
- 插件:
插件可以进行缩写,详见Maven官方文档[2]。
5. 插件目标绑定构建阶段
除了上文中Maven默认的插件目标与构建阶段的绑定,使用者可以通过配置文件将插件目标同构建阶段进行绑定[3]。如下POM文件配置示例,绑定关系见<execution>
标签中内容:
<phase>
:声明要绑定的构建阶段。<goals>
:声明绑定的插件目标列表。<configuration>
:声明插件配置。
<project>
...
<build>
<plugins>
<plugin>
<artifactId>echo-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<id>execution1</id>
<phase>test</phase>
<goals>
<goal>echo-test</goal>
<goal>echo-cost</goal>
</goals>
</execution>
<execution>
<id>execution2</id>
<phase>clean</phase>
<goals>
<goal>echo-clean</goal>
<goal>echo-cost</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
更多关于插件开发与使用的内容见官方文档[4]。
6. 附录-生命周期
6.1. Clean
Phase | Description |
---|---|
pre-clean | execute processes needed prior to the actual project cleaning |
clean | remove all files generated by the previous build |
post-clean | execute processes needed to finalize the project cleaning |
6.2. Default
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. |
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. |
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. |
6.3. Site
Phase | Description |
---|---|
pre-site | execute processes needed prior to the actual project site generation |
site | generate the project’s site documentation |
post-site | execute processes needed to finalize the site generation, and to prepare for site deployment |
site-deploy | deploy the generated site documentation to the specified web server |
7. 附录-生命周期默认绑定
7.1. Clean
Phase | plugin:goal |
---|---|
clean | clean:clean |
7.2. Default
打包方式:ejb / ejb3 / jar / par / rar / war
Phase | plugin:goal |
---|---|
process-resources | resources:resources |
compile | compiler:compile |
process-test-resources | resources:testResources |
test-compile | compiler:testCompile |
test | surefire:test |
package | ejb:ejb or ejb3:ejb3 or jar:jar or par:par or rar:rar or war:war |
install | install:install |
deploy | deploy:deploy |
打包方式:ear
Phase | plugin:goal |
---|---|
generate-resources | ear:generate-application-xml |
process-resources | resources:resources |
package | ear:ear |
install | install:install |
deploy | deploy:deploy |
打包方式:maven-plugin
Phase | plugin:goal |
---|---|
generate-resources | plugin:descriptor |
process-resources | resources:resources |
compile | compiler:compile |
process-test-resources | resources:testResources |
test-compile | compiler:testCompile |
test | surefire:test |
package | jar:jar and plugin:addPluginArtifactMetadata |
install | install:install |
deploy | deploy:deploy |
打包方式:pom
Phase | plugin:goal |
---|---|
package | |
install | install:install |
deploy | deploy:deploy |
7.3. Site
Phase | plugin:goal |
---|---|
site | site:site |
site-deploy | site:deploy |
8. 参考文档
- 1.Introduction to the Build Lifecycle – Build Lifecycle Basics – Maven ↩
- 2.Introduction to Plugin Prefix Resolution – Maven ↩
- 3.Guide to Configuring Plug-ins – Configuring Build Plugins – Maven ↩
- 4.Plugin Developers Centre – Maven ↩
- 5.Introduction to the Build Lifecycle – Lifecycle Reference – Maven ↩
- 6.components.xml at maven-3.9.9 · apache/maven ↩
- 7.Introduction to the Build Lifecycle – Built-in Lifecycle Bindings – Maven ↩
- 8.default-bindings.xml at maven-3.9.9 · apache/maven ↩