1、什么是生命周期?插件的作用?
前面我们说过,maven是一个项目构建、依赖管理的工具,生命周期就是maven在项目构建的过程中抽象出来的一系列子过程,例如编译、执行测试、打包等等过程。
需要注意的是,maven只是将生命周期进行了抽象化的定义,真正实现生命周期各个过程是插件。这样做的好处是,可以最大限度的将定制构建行为的能力提供给开发人员,开发人员甚至可以自己编写自己需要的插件,来满足自己的特性化构建需求。
2、maven的生命周期
2.1、maven的三套生命周期
对于maven的生命周期来说,共有三个相互独立的生命周期,分别是clean、default、site。
- clean生命周期目的是清理项目
- default生命周期目的是构建项目
- site生命周期目的是建立项目站点。
每个生命周期分别包含一些阶段,这些阶段是有顺序的,并且后面的阶段依赖于前面的阶段。如clean生命周期包含pre-clean、clean和post-clean三个阶段,如果执行clean阶段,则会先执行pre-clean阶段。
较之于生命周期阶段有前后依赖关系,三套生命周期本身是相互独立的,用户可以仅调用clean生命周期的某个阶段,也可以不执行clean周期,而直接执行default生命周期的某几个阶段。
2.2、clean生命周期
clean生命周期包含三个阶段,主要负责清理项目,如下:
pre-clean | executes processes needed prior to the actual project cleaning |
clean | remove all files generated by the previous build |
post-clean | executes processes needed to finalize the project cleaning |
2.3、default生命周期
default生命周期定义了真正构建时所需要执行的所有步骤,包含的阶段如下:
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 | 处理项目的主资源文件,一般来说,是对src/main/resources目录的内容进行变量替换等工作后,复制到项目输出的主classpath目录中 |
generate-resources | generate resources for inclusion in the package. |
process-resources | copy and process the resources into the destination directory, ready for packaging. |
compile | 编译项目的主源码,一般来说是编译src/main/java目录下的JAVA文件至项目的主classpath目录中 |
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 | 处理项目测试资源文件 |
generate-test-resources | create resources for testing. |
process-test-resources | copy and process the resources into the test destination directory. |
test-compile | 编译项目的测试代码 |
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 | 使用合适的单元测试框架运行测试。这些测试不应该要求对代码进行打包或部署。 |
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 | 将编译后的代码打包成可分发的格式,例如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 | 将包安装到本地存储库中,以便在本地其他项目中作为依赖项使用。 |
deploy | 在集成或发布环境中完成,将最终包复制到远程存储库,以便与其他开发人员和项目共享。 |
2.4、site生命周期
siet生命周期的目的是建立和发布项目站点,maven能够基于POM所包含的信息,自动生成一个友好的站点,方便团队交流和发布项目信息,包含的阶段如下:
pre-site | 在实际项目站点生成之前执行所需的过程 |
site | 生成项目的站点文档 |
post-site | 执行完成站点生成和准备站点部署所需的过程 |
site-deploy | 将生成的站点文档部署到指定的web服务器 |
2.5、命令行和生命周期
从命令行执行maven任务的最主要方式就是调用maven的生命周期阶段。需要注意的是,各个生命周期是相互独立的,而一个生命周期的阶段是有前后依赖关系的。例子如下:
- $mvn clean :该命令调用clean生命周期的clean阶段。实际执行的阶段为clean生命周期的pre-clean和clean阶段。
- $mvn test:该命令调用default生命周期的test阶段。实际调用的是default生命周期的validate、initialize等,直到test的所有阶段。
- $mvn clean install:该命令调换用clean生命周期的clean阶段和default生命周期的instal阶段。
- $mvn clean deploy 该命令调用了clean生命周期的clean阶段、default生命周期的deploy阶段
3、插件
3.1、插件目标
maven的核心仅仅定义了抽象的生命周期,具体的任务是交由插件完成的,插件以独立的形式存在。
对于插件本身,为了能够复用代码,它往往能够完成多个任务。如maven-dependency-plugin有十多个目标,每个目标对应了一个功能,如 dependency:analyze、 dependency:tree和dependency:list。这是一种通用的写法,冒号前面是插件前缀,后面是该插件的目标。
3.2、插件绑定
maven的生命周期与插件相互绑定,用以完成实际的构建任务。具体而言,是生命周期的阶段与插件的目标相互绑定,已完成某个具体的构建任务。例如项目编译这一任务,它对应了default生命周期的compile阶段,而maven-compiler-plugin这一插件的compile目标能够完成该任务,因此将他们绑定。
3.2.1、 内置绑定–maven默认构建行为
为了让用户能够不用任何配置就能构建maven项目,maven在核心为一些主要的生命周期默认绑定了很多插件的目标,当用户通过命令行调用生命周期阶段的时候,对应的插件目标就会执行相应的任务。
clean和site生命周期绑定的插件目标相对简单。
clean生命周期阶段 | 插件目标 |
pre-clean | |
clean | maven-clean-plugin:clean |
post-clean |
default生命周期默认插件目标绑定
deafult生命周期的阶段和插件目标的绑定关系由项目的打包理性决定(jar or war)
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生命周期还有很多其他阶段,默认它们没有绑定任何插件
3.2.2、自定义绑定
除了内置绑定以为,用户还能够自己选择奖某个插件目标绑定到生命周期的某个阶段以执行更多更特色的任务。
pom中自定义绑定插件目标
<!-- 自动复制maven依赖包到lib目录 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
<executions> <!--配置执行任务-->
<execution>
<id>copy</id>
<phase>install</phase><!--绑定生命周期-->
<goals> <!--绑定插件目标-->
<goal>copy-dependencies</goal>
</goals>
<configuration><!--配置插件参数-->
<outputDirectory>lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
上面的配置,定义了一个id为copy的任务,利用插件maven-dependency-plugin的copy-dependencies目标绑定到default生命周期的install阶段,来实现项目依赖的jar包的自动复制。
注意: 当插件目标被绑定到不同的生命周期阶段时候,其执行顺序会有生命周期阶段的先后顺序决定的。如果多个目标被绑定到同一个阶段,他们的执行顺序是由插件声明的先后顺序决定目标的执行顺序。
3.3、插件配置
3.3.1、通过命令行配置
如 $mvn install -Dmaven.test.skip=true 的意义即跳过测试步骤。
参数-D的Java自带的,其功能是通过命令行设置一个java系统属性,maven简单地重用了该参数以实现插件参数的配置。
3.3.2、在pom中进行全局配置
如项目编译使用1.6版本的源文件,生成与JVM1.6兼容的字节码文件:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration> <!--参数配置-->
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
3.4、利用目标前缀,在命令行调用插件
我们可以通过mvn命令激活生命周期阶段(例如mvn install)来执行绑定在生命周期阶段的插件目标,同时我们也可以直接调用插件的目标。
调用方式:
mvn groupId:artifactId:version:goal
例如调用显示依赖树的插件目标:
mvn org.apache.maven.plugins:maven-dependency-plugin:2.1:tree
输入完之后,你肯定会觉得,这命令是不是太长了????!!!!!
于是,maven提供了目标前缀的概念。
maven将dependency作为 org.apache.maven.plugins:maven-dependency-plugin前缀,使用
mvn dependency:tree
来调用插件目标。
3.5、插件仓库
我们前面了解过依赖构件的仓库,同样的,插件构件同样也存在于maven仓库中,但是Maven会区别对待依赖的远程仓库和插件的远程仓库。
pom中配置一个插件构件的远程仓库:(也可在setting中配置)
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Maven plugin</name>
<url>htpp://repo1.maven.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</pluginRepository>
</pluginRepositories>
配置内容与依赖的远程仓库配置元素相同,此处不予赘述。