生命周期是maven
的又一大核心,maven
的生命周期是抽象的,而实际行为都是以插件的方式来完成的,下面我将对生命周期与插件进行详细讲解
生命周期
maven
的生命周期就是为了对所有的构建进行统一和抽象,这个生命周期包括了项目的清理(clean
)、初始化、编译(compile
)、测试(test
)、打包(package
)、集成测试、验证(vertify
)、安装(install
)、部署(deploy
)和站点(site
)生成等几乎所有的构建操作
值得注意的是,我们上面所说的那些阶段并不是一个整体,其实上它被分成了三个独立的生命周期:clean
,default
,site
clean生命周期的目的是清理项目
default生命周期的目的是构建项目
site生命周期的目的是建立项目站点
每一个生命周期包含一些阶段(phase
),这些阶段是有顺序的,并且后面的阶段会依赖于前面的阶段
maven
的三套生命周期是相互独立的,他们各自包含不同的阶段
clean生命周期
pre-clean
执行一些清理项目之前的准备工作
clean
清理上一次构建生成的文件
post-clean
执行一些清理之后需要完成的工作
default生命周期
default
生命周期定义了真正构建时所需要执行的所有步骤,是最为核心的生命周期
validate
对项目进行验证
initialize
执行生命周期初始化操作
generate-sources
生成所有在编译过程中的源代码(java文件)
process-sources
处理源代码,比如过滤某些值
generate-resources
生成需要在编译过程中的资源文件
process-resources
复制和处理资源文件,比如变量替换等操作
compile
对项目主代码src/main/java
下的java
文件进行编译输出到classpath
目录中
process-classes
编译后处理,比如java
类的字节码增强操作
generate-test-sources
处理项目测试源文件
process-test-sources
处理项目测试资源文件,一般是对src/test/resources
目录内容进行变量替换等操作
generate-test-resources
生成测试资源文件针对src/test/resources
目录下的资源文件
process-test-resources
处理生成的测试资源文件,比如变量替换等操作
test-compile
process-test-classes
test
使用单元测试框架运行测试,测试代码不会被打包和部署
prepare-package
项目打包之前的一些操作
package
项目打包
pre-integration-test
项目集成测试之前的操作
integration-test
集成测试
post-integration-test
测试完成后的操作
verify
执行所有检查,验证包是否有效
install
将项目安装到本地仓库中
deploy
将最终的包复制到远程仓库
在IDEA IDE中也给出了一些我们日常工作开发中常用的生命周期阶段
site生命周期
pre-site
生成站点之前做一些准备工作
site
生成项目站点
post-site
站点生成完毕后执行的一些处理
site-deploy
将站点发布到服务器上
命令行与生命周期
我们可以通过在cmd
中输入maven
命令来执行maven
生命周期,比如:
mvn clean
执行clean
生命周期的pre-clean clean
阶段
mvn test
执行default
生命周期中的validate/initialize/generate-sources/process-sources/generate-resources/process-resources/compile/post-classes/generate-test-sources/process-test/sources/generate-test-resources/process-test-resources/test-compile/post-test-classes/test
,也就是位于test阶段之前的所有阶段都会被执行,这主要是因为maven生命周期中的阶段是有先后顺序导致的,执行某一阶段将会把位于它前面的阶段都执行完毕
mvn clean install
执行clean
生命周期clean
阶段之前的所有阶段以及default
生命周期install
阶段之前的所有阶段
需要注意的是在执行项目构建之前清理项目是一个很好的实践,也就是通过下面的方式来执行各个阶段:
mvn clean _phase_
插件目标
插件是作为抽象的maven
生命周期的实现,是以独立构件的方式进行发布
插件往往能实现许多任务,这些任务可以组合成许多功能,这些功能就成为了插件的目标
比如maven-dependency-plugin
存在
dependency:analyze
分析maven
依赖情况
dependency:tree
树形展示maven依赖
dpendency:list
列表展示maven依赖
插件绑定
maven
生命周期实际不做任务操作,在执行实际的操作时生命周期阶段需要绑定到具体插件的某一个目标上,用以完成某个具体的构建任务
在maven
生命周期的某些阶段中已经默认绑定了具体的插件目标,如果生命周期的各个阶段没有绑定具体的插件目标,那么这些阶段其实是没有任何实际行动的
比如clean
生命周期的clean
阶段与maven-clean-plugin:clean
目标进行绑定用于删除项目的输出目录default
生命周期的test
阶段与maven-surefire-plugin:test
目标进行绑定,用以执行junit
测试
自定义插件绑定
用户可以选择将某一个插件的目标绑定到生命周期的某一个阶段,下面是一个打包源码jar
包的例子
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.1</version>
<executions>
<execution>
<id>attache-sources</id>
<phase>verify</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
上面的打包源码包任务被绑定到了default
生命周期的vertify
阶段上,当执行mvn clean vertify
时就会在target
目录下看到源码包
上面的配置也可以简化,我们可以不用指定phase
生命周期阶段,某些插件目标默认就配置好了需要执行的生命周期阶段,可以通过maven-help-plugin
来查看插件的信息,比如说下面的命令用来查看maven-source-plugin插件的详细配置信息
mvn help:describe -Dplugin=org.apache.maven.plugins:maven-source-plugin:2.1.1 -Ddetail
source:jar-no-fork Description: This goal bundles all the sources into a jar archive. This goal functions the same as the jar goal but does not fork the build and is suitable for attaching to the build lifecycle. Implementation: org.apache.maven.plugin.source.SourceJarNoForkMojo Language: java
Bound to phase: package
表示当前jar-no-fork
目标绑定到default
生命周期的package
阶段
当然在配置目标的时候是采用的goals
数组,也就意味着可以配置多个插件目标,同一个生命周期阶段的多个插件目标按照声明的顺序执行
插件配置
命令行参数
在命令行中指定插件的参数,命令行中对应的参数信息是插件参数对应的user property
通过上面的maven-help-plugin
可以查看到具体某一个插件的详细信息,因此我们可以在命令行中使用插件参数给出的对应user property
mvn install -Dmaven.test.skip=true
表示在安装项目包到本地仓库时忽略test
阶段的junit
测试,这是由maven-surefire-plugin
提供的一个参数
skip (Default: false) User property: maven.test.skip Set this to 'true' to bypass unit tests entirely. Its use is NOT RECOMMENDED, especially if you enable it using the 'maven.test.skip' property, because maven.test.skip disables both running the tests and compiling the tests. Consider using the skipTests parameter instead.
pom全局配置
在pom
文件中定义插件时给出参数,这时这些参数对该插件的所有目标都有效,比如maven-compiler-plugin
配置编译环境
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
配置插件任务
目的在于配置插件在执行指定目标时再额外执行的工作任务
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<id>ant-validate</id>
<phase>validate</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<task>
<echo> validate run </echo>
</task>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
在执行maven clean validate
时,maven
除了会执行插件maven-antrun-plugin
中的run
目标,同时还会执行tasks
中的echo
任务并打印出validate run
字样
在线插件信息
maven
的插件实在是太多了,我们可以在下面地址上去查找需要的插件
插件列表:
http://maven.apache.org/plugins/index.html
所有插件可以在这里下载:
http://repo1.maven.org/maven2/org/apache/maven/plugins/
当然要查看某一个插件的信息,也可以通过maven-help-plugin
插件
使用maven-help-plugin
的describe
目标时需要描述插件的groupId,artifactId,version,
mvn help:describe -Dplugin=org.apache.maven.plugins:maven-complier-plugin:2.1
其中version
可以省略
mvn help:describe -Dplugin=org.apache.maven.plugins:maven-complier-plugin
更可以使用插件前缀换坐标(如果你知道的话)
mvn help:describe -Dplugin=compiler
查看某个插件的目标信息:添加-goal
参数
mvn help:describe -Dplugin=compiler -Dgoal=compile
`compiler:compile
Description: Compiles application sources
For more information, run 'mvn help:describe [...] -Ddetail'`
查看插件详细信息添加-detail
mvn help:describe -Dplugin=compiler -Ddetail
compiler:compile Description: Compiles application sources Implementation: org.apache.maven.plugin.compiler.CompilerMojo Language: java Bound to phase: compile Available parameters: annotationProcessorPaths Classpath elements to supply as annotation processor path. If specified, the compiler will detect annotation processors only in those classpath elements. If omitted, the default classpath is used to detect annotation processors. The detection itself depends on the configuration of annotationProcessors...
命令行调用插件
maven
中可以通过执行生命周期的方式来执行插件,也可以通过直接在命令行中执行插件目标,需要借助插件的前缀,比如:
mvn help:describe -Dplugin=compiler mvn dependency:tree
这里需要强调的是,能够使用命令行简化的调用插件是有限制的,必须是org.apache.maven.plugins
和org.codehaus.mojo
两个groupId
下才可以,如果其他groupId
下的插件想要在命令行简化的调用插件,需要对settings.xml
做一些文章
<settings>
<pluginGroups>
<pluginGroup>org.mortbay.jetty</pluginGroup>
</pluginGroups>
</settings>
上面的配置对groupId
为org.mortbay.jetty
的jetty-maven-plugin
插件做了设置,这样就可以在命令行中通过mvn jetty:run
方式运行jetty
容器了
插件解析机制
插件也提供了插件仓库的配置方式,当maven
命令需要执行插件时,首先回去本地插件仓库找,如果没找到,就在远程插件仓库中找
这里的插件仓库与之前的依赖仓库是独立的
下面是超级pom中定义的插件仓库设置,可以看到对于插件的snapshot是不允许上传下载的
<pluginRepositorys>
<pluginRepository>
<id>central</id>
<name>Maven Plugin Repository</name>
<url>http://repo1.maven.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
</pluginRepositorys>