生命周期
在有关Maven的日常使用中,命令行的输入往往就对应了生命周期,如mvn package就表示执行默认生命周期阶段package.
生命周期概念
Maven的生命周期就是为了对所有的构建过程进行抽象和统一,这个生命周期包含了项目的清理、初始化、编译、测试、打包、集成测试、
验证、部署和站点生成等几乎所有构建步骤。即几乎所有项目的构建,都能映射到这样一个生命周期上。
Maven的生命周期是抽象的,这意味着生命周期本身不做任何实际的工作,在Maven的设计中,实际的任务(如编译源代码)都交由插件来完成。
生命周期抽象了构建的各个步骤,定义了他们的次序,但没有提供具体实现,Maven通过插件机制,每个构建步骤都可以绑定一个或者
多个插件行为,而且Maven为大多数构建步骤编写并绑定了默认插件。
Maven定义的生命周期和插件机制一方面保证了所有Maven项目有一致的构建标准,另一方面又通过默认插件简化和稳定了实际项目的构建。
此外,该机制还提供了足够的扩展空间,用户可以通过配置现有插件或者自行编写插件来自定义构建行为。
三套生命周期:分别为clean、default、site
每个生命周期包含一些阶段(phase),这些阶段是有顺序的,并且后面的阶段依赖于前面的阶段,用户和Maven最直接的交互方式就是调用这些
生命周期阶段。
较之于生命周期阶段的前后依赖关系,三套生命周期本身是相互独立的,用户可以仅仅调用clean生命周期的某个阶段,或者仅仅调用default
生命周期的某个阶段,而不会对其他生命周期产生任何影响。
clean生命周期:目的是清理项目,包含pre-clean,clean,post-clean
default生命周期:目的是构建项目,定义了真正构建时所需要执行的所有步骤,它是所有生命周期中最核心的部分,包含如下阶段:
validate
initialize
generate-sources
process-sources
generate-resources
process-resources:处理项目主资源文件,一般来说是对src/main/resources目录的内容进行变量替换等工作后,复制到项目输出的主classpath目录中
compile
process-classes
generate-test-sources
process-test-sources
generate-test-resources
process-test-resources
test-compile
process-test-classes
test:使用单元测试框架运行测试,测试代码不会被打包或部署
prepare-package
package:接受编译好的代码,打包成可发布的格式,如jar
pre-integration-test
integration-test
post-integration-test
verify
install:将包安装到Maven本地仓库,供本地其他Maven项目使用
deploy:将最终的包复制到远程仓库,供其他开发人员和Maven项目使用
site生命周期:目的是建立和发布项目站点,Maven能够基于POM所包含的信息,自动生成一个友好的站点
方便团队交流和发布项目信息,包含如下阶段
pre-site
site
post-site
site-deploy:将生成的项目站点发布到服务器上。
命令执行与生命周期
$mvn clean:该命令调用clean生命周期的clean阶段。实际执行的阶段为clean生命周期的pre-clean和clean
$mvn test:该命令调用default生命周期的test阶段。实际执行的阶段为default生命周期的validate、initialize等,
直到test的所有阶段
$mvn clean deploy site-deploy:该命令调用clean生成周期的clean阶段、default生成周期的deploy阶段,以及site生命
周期的site-deploy阶段。实际执行的阶段为clean生命周期的pre-clean,clean阶段,default生命周期的所有阶段,
以及site生命周期的所有阶段。
插件绑定:
Maven的生命周期与插件相互绑定,用以完成实际的构建任务,具体而言,是生命周期的阶段与插件的目标相互绑定,以完成某个具体的
构建任务
如dependency:analyze,dependency:tree,dependency:list,冒号后面是插件maven-dependency-plugin的目标,
compiler:compile, surefire:test
default生命周期的阶段与插件目标的绑定关系是由项目打包类型决定,打包类型是通过POM中的packaging元素定义的。
除了内置绑定外,还可以自定义绑定,用户还能够自己选择将某个插件目标绑定到生命周期的某个阶段上。如创建项目的源代码jar包
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>compile</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
phase元素是可选的,因为有很多插件的目标在编写时已经定义了默认绑定阶段,可以使用maven-help-plugin查看插件详细信息,了解插件
目标的默认绑定阶段。
运行命令如下:
$mvn help:describe -Dplugin=org.apache.maven.plugins:maven-source-plugin:2.2.1
$mvn help:describe -Dplugin=org.apache.maven.plugins:maven-compiler-plugin:2.3.2
查看maven-surefire-plugin插件test目标的详细介绍
mvn surefire:help -Ddetail=true -Dgoal=test
当插件目标被绑定到不同的生命周期阶段的时候,其执行顺序会由生命周期阶段的先后顺序决定
如果多个目标被绑定到同一个阶段,这些插件声明的先后顺序决定了目标的执行顺序
插件配置
用户可以配置插件目标的参数,进一步调整插件目标所执行的任务,以满足项目的需求
命令行插件配置:
maven-surefire-plugin提供了一个maven.test.skip的参数,当其值为true的时候,就会跳过执行测试。
mvn package -Dmaven.test.skip=true
参数-D是Java自带的,其功能是通过命令设置一个Java系统属性,Maven简单地重用了该参数,在准备参数
的时候检查系统属性,便实现了插件参数的配置
POM中插件全局配置(为插件配置全局参数)
并不是所有的插件参数都适合从命令行配置,有些参数的值从项目创建到项目发布都不会改变,或者说很少改变,
对于这种情况,在POM文件中一次性配置就显然比重复在命令行输入要方便。
用户可以在声明插件的时候,对此插件进行一个全局的配置,即所有该基于该插件目标的任务,都会使用这些配置。
如通常会需要配置maven-compiler-plugin告诉它编译Java1.6版本的源文件,生成与JVM1.6兼容的字节码文件。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
POM中插件任务配置:为某个插件任务配置特定的参数
如maven-antrun-plugin,它有一个目标run,可以用来在Maven中调用ant任务。
获取插件信息
因为大部分插件完善的文档,因此使用正确的插件并进行正确的配置,并不是一件容易的事
基本上所有主要的Maven插件都来自Apache和Codehaus
除了Apache上的官方插件之外,托管于Codehaus上的Mojo项目也提供了大量的Maven插件
http://maven.apache.org/plugins/index.html
http://repo.maven.apache.org/maven2/org/apache/maven/plugins/
http://mojo.codehaus.org/plugins.html
http://repository.codehaus.org/org/codehaus/mojo/ (目前下面无内容)
注意:这些插件的文档和可靠性相对较差,在使用时,如果遇到问题,往往只能自己看源代码。
googlecode插件列表:
http://code.google.com/hosting/search?q=maven+plugin+label%3Amaven&projectsearch=Search+Project
不加版本信息,是让Maven自动获取最新版本来进行表述:
$mvn help:describe -Dplugin=org.apache.maven.plugins:maven-source-plugin:2.2.1
$mvn help:describe -Dplugin=org.apache.maven.plugins:maven-compiler-plugin:2.3.2
查看maven-surefire-plugin插件test目标的详细介绍
mvn help:describe -Dplugin=compiler
mvn help:describe -Dplugin=compiler -Ddetail=true
mvn help:describe -Dplugin=compiler -Dgoal=compile
mvn surefire:help -Ddetail=true -Dgoal=test
从命令行调用插件
usage: mvn [options] [<goal(s)>] [<phase(s)>]
options 表示可用的选项
除了选项之外,mvn命令后面可以添加一个或者多个goal和phase,它们分别是指插件目标和生命周期阶段
可以通过mvn命令激活生命周期阶段,从而执行那些绑定在生命周期阶段上的插件目标,
还支持直接从命令行调用插件目标,因为有些任务不适合绑定在生命周期上,
如maven-help-plugin:describe :不需要在构建项目的时候去描述插件信息
maven-dependency-plugin:tree:不需要在构建项目的时候去显示依赖树
因为这些插件目标应该通过如下方式使用
mvn help:describe -Dplugin=compiler
mvn dependency:tree
mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:describe -Dplugin=compiler
这种方式是通过插件前缀实现的(否则要写全groupId、artifactId、version),有了插件前缀,Maven就能找到对应的artifactId
插件解析机制
为了方便用户使用和配置插件,Maven不需要用户提供完整的插件坐标信息,就可以解析得到正确的插件。
插件仓库
插件同样基本坐标存储在Maven仓库中。Maven会区别对待依赖的远程仓库和插件的远程仓库
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Central Repository</name>
<url>http://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
</pluginRepositories>
1:插件从来不从远程仓库检查更新
2:插件的默认groupId为org.apache.maven.plugins,如果是Maven的官方插件,则可以省略groupId配置
解析插件版本:
1:Maven在超级POM中为所有核心插件设定了版本,超级POM是所有Maven项目的父POM,所有项目都继承这个
超级POM的配置
2:如果使用某个插件没有设定版本,而此插件又不属于核心插件的范畴,Maven就会检查最新的RELEASE版本
3:解析插件前缀:插件前缀与groupId:artifactId是一一对应的,这种匹配关系存储在仓库元数据中。
这里的仓库元数据为groupId/maven-metadata.xml
http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-metadata.xml
在有关Maven的日常使用中,命令行的输入往往就对应了生命周期,如mvn package就表示执行默认生命周期阶段package.
生命周期概念
Maven的生命周期就是为了对所有的构建过程进行抽象和统一,这个生命周期包含了项目的清理、初始化、编译、测试、打包、集成测试、
验证、部署和站点生成等几乎所有构建步骤。即几乎所有项目的构建,都能映射到这样一个生命周期上。
Maven的生命周期是抽象的,这意味着生命周期本身不做任何实际的工作,在Maven的设计中,实际的任务(如编译源代码)都交由插件来完成。
生命周期抽象了构建的各个步骤,定义了他们的次序,但没有提供具体实现,Maven通过插件机制,每个构建步骤都可以绑定一个或者
多个插件行为,而且Maven为大多数构建步骤编写并绑定了默认插件。
Maven定义的生命周期和插件机制一方面保证了所有Maven项目有一致的构建标准,另一方面又通过默认插件简化和稳定了实际项目的构建。
此外,该机制还提供了足够的扩展空间,用户可以通过配置现有插件或者自行编写插件来自定义构建行为。
三套生命周期:分别为clean、default、site
每个生命周期包含一些阶段(phase),这些阶段是有顺序的,并且后面的阶段依赖于前面的阶段,用户和Maven最直接的交互方式就是调用这些
生命周期阶段。
较之于生命周期阶段的前后依赖关系,三套生命周期本身是相互独立的,用户可以仅仅调用clean生命周期的某个阶段,或者仅仅调用default
生命周期的某个阶段,而不会对其他生命周期产生任何影响。
clean生命周期:目的是清理项目,包含pre-clean,clean,post-clean
default生命周期:目的是构建项目,定义了真正构建时所需要执行的所有步骤,它是所有生命周期中最核心的部分,包含如下阶段:
validate
initialize
generate-sources
process-sources
generate-resources
process-resources:处理项目主资源文件,一般来说是对src/main/resources目录的内容进行变量替换等工作后,复制到项目输出的主classpath目录中
compile
process-classes
generate-test-sources
process-test-sources
generate-test-resources
process-test-resources
test-compile
process-test-classes
test:使用单元测试框架运行测试,测试代码不会被打包或部署
prepare-package
package:接受编译好的代码,打包成可发布的格式,如jar
pre-integration-test
integration-test
post-integration-test
verify
install:将包安装到Maven本地仓库,供本地其他Maven项目使用
deploy:将最终的包复制到远程仓库,供其他开发人员和Maven项目使用
site生命周期:目的是建立和发布项目站点,Maven能够基于POM所包含的信息,自动生成一个友好的站点
方便团队交流和发布项目信息,包含如下阶段
pre-site
site
post-site
site-deploy:将生成的项目站点发布到服务器上。
命令执行与生命周期
$mvn clean:该命令调用clean生命周期的clean阶段。实际执行的阶段为clean生命周期的pre-clean和clean
$mvn test:该命令调用default生命周期的test阶段。实际执行的阶段为default生命周期的validate、initialize等,
直到test的所有阶段
$mvn clean deploy site-deploy:该命令调用clean生成周期的clean阶段、default生成周期的deploy阶段,以及site生命
周期的site-deploy阶段。实际执行的阶段为clean生命周期的pre-clean,clean阶段,default生命周期的所有阶段,
以及site生命周期的所有阶段。
插件绑定:
Maven的生命周期与插件相互绑定,用以完成实际的构建任务,具体而言,是生命周期的阶段与插件的目标相互绑定,以完成某个具体的
构建任务
如dependency:analyze,dependency:tree,dependency:list,冒号后面是插件maven-dependency-plugin的目标,
compiler:compile, surefire:test
default生命周期的阶段与插件目标的绑定关系是由项目打包类型决定,打包类型是通过POM中的packaging元素定义的。
除了内置绑定外,还可以自定义绑定,用户还能够自己选择将某个插件目标绑定到生命周期的某个阶段上。如创建项目的源代码jar包
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>compile</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
phase元素是可选的,因为有很多插件的目标在编写时已经定义了默认绑定阶段,可以使用maven-help-plugin查看插件详细信息,了解插件
目标的默认绑定阶段。
运行命令如下:
$mvn help:describe -Dplugin=org.apache.maven.plugins:maven-source-plugin:2.2.1
$mvn help:describe -Dplugin=org.apache.maven.plugins:maven-compiler-plugin:2.3.2
查看maven-surefire-plugin插件test目标的详细介绍
mvn surefire:help -Ddetail=true -Dgoal=test
当插件目标被绑定到不同的生命周期阶段的时候,其执行顺序会由生命周期阶段的先后顺序决定
如果多个目标被绑定到同一个阶段,这些插件声明的先后顺序决定了目标的执行顺序
插件配置
用户可以配置插件目标的参数,进一步调整插件目标所执行的任务,以满足项目的需求
命令行插件配置:
maven-surefire-plugin提供了一个maven.test.skip的参数,当其值为true的时候,就会跳过执行测试。
mvn package -Dmaven.test.skip=true
参数-D是Java自带的,其功能是通过命令设置一个Java系统属性,Maven简单地重用了该参数,在准备参数
的时候检查系统属性,便实现了插件参数的配置
POM中插件全局配置(为插件配置全局参数)
并不是所有的插件参数都适合从命令行配置,有些参数的值从项目创建到项目发布都不会改变,或者说很少改变,
对于这种情况,在POM文件中一次性配置就显然比重复在命令行输入要方便。
用户可以在声明插件的时候,对此插件进行一个全局的配置,即所有该基于该插件目标的任务,都会使用这些配置。
如通常会需要配置maven-compiler-plugin告诉它编译Java1.6版本的源文件,生成与JVM1.6兼容的字节码文件。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
POM中插件任务配置:为某个插件任务配置特定的参数
如maven-antrun-plugin,它有一个目标run,可以用来在Maven中调用ant任务。
获取插件信息
因为大部分插件完善的文档,因此使用正确的插件并进行正确的配置,并不是一件容易的事
基本上所有主要的Maven插件都来自Apache和Codehaus
除了Apache上的官方插件之外,托管于Codehaus上的Mojo项目也提供了大量的Maven插件
http://maven.apache.org/plugins/index.html
http://repo.maven.apache.org/maven2/org/apache/maven/plugins/
http://mojo.codehaus.org/plugins.html
http://repository.codehaus.org/org/codehaus/mojo/ (目前下面无内容)
注意:这些插件的文档和可靠性相对较差,在使用时,如果遇到问题,往往只能自己看源代码。
googlecode插件列表:
http://code.google.com/hosting/search?q=maven+plugin+label%3Amaven&projectsearch=Search+Project
不加版本信息,是让Maven自动获取最新版本来进行表述:
$mvn help:describe -Dplugin=org.apache.maven.plugins:maven-source-plugin:2.2.1
$mvn help:describe -Dplugin=org.apache.maven.plugins:maven-compiler-plugin:2.3.2
查看maven-surefire-plugin插件test目标的详细介绍
mvn help:describe -Dplugin=compiler
mvn help:describe -Dplugin=compiler -Ddetail=true
mvn help:describe -Dplugin=compiler -Dgoal=compile
mvn surefire:help -Ddetail=true -Dgoal=test
从命令行调用插件
usage: mvn [options] [<goal(s)>] [<phase(s)>]
options 表示可用的选项
除了选项之外,mvn命令后面可以添加一个或者多个goal和phase,它们分别是指插件目标和生命周期阶段
可以通过mvn命令激活生命周期阶段,从而执行那些绑定在生命周期阶段上的插件目标,
还支持直接从命令行调用插件目标,因为有些任务不适合绑定在生命周期上,
如maven-help-plugin:describe :不需要在构建项目的时候去描述插件信息
maven-dependency-plugin:tree:不需要在构建项目的时候去显示依赖树
因为这些插件目标应该通过如下方式使用
mvn help:describe -Dplugin=compiler
mvn dependency:tree
mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:describe -Dplugin=compiler
这种方式是通过插件前缀实现的(否则要写全groupId、artifactId、version),有了插件前缀,Maven就能找到对应的artifactId
插件解析机制
为了方便用户使用和配置插件,Maven不需要用户提供完整的插件坐标信息,就可以解析得到正确的插件。
插件仓库
插件同样基本坐标存储在Maven仓库中。Maven会区别对待依赖的远程仓库和插件的远程仓库
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Central Repository</name>
<url>http://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
</pluginRepositories>
1:插件从来不从远程仓库检查更新
2:插件的默认groupId为org.apache.maven.plugins,如果是Maven的官方插件,则可以省略groupId配置
解析插件版本:
1:Maven在超级POM中为所有核心插件设定了版本,超级POM是所有Maven项目的父POM,所有项目都继承这个
超级POM的配置
2:如果使用某个插件没有设定版本,而此插件又不属于核心插件的范畴,Maven就会检查最新的RELEASE版本
3:解析插件前缀:插件前缀与groupId:artifactId是一一对应的,这种匹配关系存储在仓库元数据中。
这里的仓库元数据为groupId/maven-metadata.xml
http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-metadata.xml