生命周期
Maven有三套独立的生命周期,分别为clean、default、site。每个生命周期包含一些阶段(phase),这些阶段是有顺序的,并且后面的阶段依赖于前面的阶段。三套生命周期是相互独立的,用户可以仅仅调用clean生命周期的某个阶段,或者仅仅调用default生命周期的某个阶段,而不会对其他生命周期产生任何影响。当调用clean生命周期的clean阶段的时候,不会触发default生命周期的任何阶段,当调用default生命周期的compile阶段的时候,也不会触发clean生命周期的任何阶段。
详细说明参考
https://maven.apache.org/ref/3.9.9/maven-core/lifecycles.html#default_Lifecycle
https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
clean生命周期,目的是清理项目
1、pre-clean 执行一些清理前需要完成的工作
2、clean 清理上一次构建生成的文件
3、post-clean 执行一些清理后需要完成的工作
default 生命周期
定义了真正构建时所需要执行的所有步骤,核心生命周期
1、validate
2、initialize
3、generate-sources
4、process-sources 处理项目主资源文件。一般来说是对src/main/resources 目录的内容进行变量替换等工作后,复制到项目输出的主classpath目录中。
5、generate-resources
6、process-resources
7、 compile 编译项目主源码。一般来说是编译src/main/java 目录下的java文件至项目输出的主classpath目录中。
8、process-classes
9、generate-test-sources
10、process-test-sources 处理项目测试资源文件。一般来说,是对src/test/resources目录的内容进行变量替换等工作后,复制到项目输出的测试classpath目录中。
11、generate-test-resources
12、process-test-resources
13、test-compile 编译项目的测试代码。一般来说是编译src/test/java目录下的java文件之项目输出的测试classpath目录中。
14、process-test-classes
15、test 使用单元测试框架运行测试。测试代码不会被打包或部署。
16、prepare-package
17、package 接受编译好的代码,打包成可发布的格式,如jar
18、pre-integration-test
19、integration-test
20、post-integration-test
21、verify
22、install 将包安装到Maven本地仓库,共本地其他Maven项目使用
23、deploy 将最终的包复制到远程仓库,供其他开发人员和Maven项目使用。
site生命周期
目的是建立和发布项目站点,Maven能够基于POM所包含的信息,自动生成一个友好的站点,方便团队交流和发布项目信息。
1、pre-site 执行一些在生成项目站点之前需要完成的工作
2、site 生成项目站点文档
3、post-site 执行一些在生成项目站点之后需要完成的工作
4、site-deploy 将生成的项目站点发布到服务器上
插件
内置绑定
Maven的生命周期和插件相互绑定,用以完成实际的构建任务。
mvn dependency:tree
mvn dependency:list
mvn dependency:analyze
冒号前面是插件前缀,后面是插件目标。Maven 内置生命周期绑定了对应的插件的目标,例如clean与maven-clean-plugin:clean 绑定,site与maven-site-plugin相互绑定,site-deploy与maven-site-plugin:deploy互相绑定。
除了默认的打包类型jar外,常见的打包类型还有war,pom,maven-plugin,ear。它们的default命周期与插件目标的绑定关系可参阅Maven方文档:
https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Built-in_Lifecycle_Bindings
自定义绑定生命周期与插件目标
一般插件都有默认绑定的生命周期的阶段phase,修改pom自定义绑定插件目标至阶段。示例中配置了id为attach-sources的任务,通过phase配置,将其绑定到verify生命周期阶段上。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins<groupId/>
<artifactId>maven-source-plugin<artifactId/>
<version>2.1.2</version>
<executions>
<execution>
<id>attach-sources<id/>
<goals>
<goal>jar-no-fork<goal/>
<goals/>
<phase>verify<phase/>
</execution>
</executions>
</plugin>
</plugins>
</build>
有很多插件的目标在编写时已经定义了默认绑定阶段,即使不通过phase元素配置生命周期阶段,插件目标也能够绑定到生命周期中去。
使用maven-help-plugin可以查看插件的详细信息,eg:
mvn help:describe -Dplugin=org.apache.maven.plugins:maven-source-plugin:2.1.1 -Ddetail
当插件目标被绑定到不同的的生命周期阶段的时候,其执行顺序会由生命周期阶段的先后顺序决定,如果多个目标被绑定到同一个阶段,这些插件声明的先后顺序决定了目标的执行顺序。
在描述插件的时候,还可以省去版本信息,让Maven自动获取最新版本来进行表述
eg: mvn help:describe -Dplugin=org.apache.maven.plugins:maven-source-plugin
进一步简化可以使用插件目标前缀替换坐标
eg: mvn help:describe -Dplugin=source
如果仅仅描述某个插件目标信息,可以加上goal参数
eg: mvn help:describe -Dplugin=compiler -Dgoal=compile
如果想让maven-help-plugin输出更详细的信息,可以加上detail参数
eg: mvn help:describe -Dplugin=compiler -Dgoal=compile -Ddetail
插件参数配置
命令行配置:参数经常变化适合命令行配置。Maven命令中使用 -D 参数,并伴随一个参数键 = 参数值的形式,来配置插件目标的参数。参数-D是Java自带的,其功能是通过命令行设置一个Java系统属性,Maven简单的重用了该参数,在准备插件的时候检查系统属性,便实现了插件参数的配置。如上边查看插件详细信息命令
POM文件一次性配置:从项目创建到项目发布都不会改变或者说很少改变,适于文件配置插件配置全局参数
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins<groupId/>
<artifactId>maven-compile-plugin<artifactId/>
<version>2.1</version>
<configuration>
<source>1.5<source/>
<target>1.5<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/>
<goals>
<goal>run<goal/>
</goals>
<phase>validate<phase/>
<configuration>
<tasks>
<echo>I'm bound to validate phase.<echo/>
</tasks>
</configuration>
<execution>
<execution>
<id>ant-verify<id/>
<goals>
<goal>run<goal/>
</goals>
<phase>verify<phase/>
<configuration>
<tasks>
<echo>I'm bound to verify phase.<echo/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
插件全局配置中的configuration元素位于plugin元素下面,位于execution元素下的configuration表示是特定任务的配置,而非插件整体的配置。
maven官方插件
插件列表:http://maven.apache.org/plugins/index.html
下载插件: Central Repository: org/apache/maven/plugins
插件解析机制
插件和依赖在不指定版本时Maven3默认都是去依赖仓库或者插件仓库去下载release版本,Maven2默认会解析latest版本
依赖(发布版)的元数据位置:groupId/artifactId/maven-metadata.xml,在对应artifactId目录下
插件(发布版)的元数据位置:groupId/artifactId/maven-metadata.xml,在对应artifactId目录下
插件仓库的元数据位置为groupId/maven-metadata-xml 官网插件仓库元数据位置就是plugins下即org/apache/maven/plugins下面
如果插件是Maven官方的插件,POM中配置插件时可以省略groupId(org.apache.maven.plugins)
解析插件版本
指定插件版本的情况与依赖版本的解析相类似,没有指定插件版本的分为核心插件和非核心插件
核心插件的版本一般都是在超级POM中定义好了版本号,不同的maven版本,插件版本不同
如果是非核心插件检查所有仓库中可用的版本然后做出选择,具体过程如下:
遍历本地仓库和所有远程插件仓库->合并插件元数据->计算出latest和release的值->Maven3默认使用release版本,Maven2默认使用latest版本
解析插件前缀
命令行使用插件前缀来简化插件的调用,现在解释Maven如何根据插件前缀解析得到插件的坐标。
通过前缀搜索仓库元数据,Maven在解析插件仓库元数据的时候会默认使用org.apache.maven.plugins和org.codehaus.mojo两个groupId,也可以通过配置settings.xml让Maven检查其他groupId上的插件仓库元数据:
<settings>
<pluginGroups>
<pluginGroup>com.your.plugins<pluginGroup/>
</pluginGroups>
</settings>
根据仓库元数据获得插件的groupId和artifactId,根据groupId和artifactId遍历本地和远程插件仓库,将仓库元数据归并后计算出对应的版本号,进而得到插件的完整坐标。如果仓库元数据(org/apache/maven/plugins/maven-metadata.xml)没有记录插件前缀,则接着检查其他groupId(例如org/codehaus/mojo/maven-metadata.xml)下的元数据,以及用户自定义的插件组,如果所有的元数据中都不含对应的前缀,则报错。