Maven用户都应该知道的一些事:构建生命周期和插件

Maven的所有实际操作都是由插件完成的,如果没有插件,Maven什么都不会干。
(即时你没有在POM中配置<plugin>元素,Super POM中也已经帮你引入了若干核心插件)

那么问题来了,项目构建过程中,Maven是怎么知道应该在什么时候调用哪个插件的呢?

插件的调用时机,跟’生命周期’和’插件目标’有很大关系。

插件目标(Plugin Goal)是个什么鬼

首先需要知道的是,Maven的所有具体任务都是交由插件实现的,而一个插件往往能实现若干个任务或功能。又或者可以说一个插件能实现若干个目标,比如编译源码、执行测试用例、打包项目等等。
简单来说,在Maven中Plugin Goal可以看做是插件的一个功能。

Plugin Goal通常用‘插件前缀:插件目标‘的格式描述,常见的有:compiler:compile,surefire:test,dependency:tree等。

所谓插件前缀就是插件的名称的一个简写,比如compiler指的就是maven-complier-plugin这个插件。
compiler:compile的意思既是maven-complier-plugin插件的compile目标。

构建生命周期(Build Lifecycle)又是什么

构建生命周期是对构建过程的抽象和统一,包括了几乎所有的构建步骤,如清理、初始化、编译、测试、打包等等。

Maven为不用的目的定义了3套相互独立的生命周期:

  • clean 用于清理项目
  • default 用于构建项目
  • site 用于构建项目站点

每种生命周期都是由若干阶段(phase)组成,如clean生命周期由pre-clean,clean,post-clean三个阶段组成。

阶段之间是有序的,而且后面的阶段依赖前面的阶段。
用户执行mvn clean时,实际上maven会先执行pre-clean阶段,然后再执行clean阶段;执行mvn post-clean时,则会依次执行pre-clean,clean,post-clean三个阶段。

3个生命周期各自的阶段如下:

Clean Lifecycle

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

Default Lifecycle

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 Lifecycle

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

插件目标与生命周期的绑定

插件目标是与生命周期的某个阶段绑定的,比如maven-clean-plugin的clean目标与clean阶段绑定,也就意味着当maven执行clean生命周期时,到达clean阶段的时候,会调用maven-clean-plugin的clean目标(删除项目输出目录)。

也就是说,插件目标的执行顺序是由其绑定到的生命周期阶段的顺序决定的,如果多个插件目标绑定到同一个阶段,那么先声明的插件会在后声明的插件之前执行。

对于一些核心插件,Maven已经内置默认将一些插件目标绑定到了生命周期阶段,特别是default生命周期,对于不同的打包类型(jar,war,pom等),Maven提供了不同的默认绑定。如下所示:

Clean Lifecycle Bindings

Phase plugin:goal
clean clean:clean

Default Lifecycle Bindings - Packaging 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

Default Lifecycle Bindings - Packaging ear

Phase plugin:goal
generate-resources ear:generate-application-xml
process-resources resources:resources
package ear:ear
install install:install
deploy deploy:deploy

Default Lifecycle Bindings - Packaging 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

Default Lifecycle Bindings - Packaging pom

Phase plugin:goal
package
install install:install
deploy deploy:deploy

Site Lifecycle Bindings

Phase plugin:goal
site site:site
site-deploy site:deploy

参考文献

转载请保留原文地址:Maven用户都应该知道的一些事:构建生命周期和插件