maven的生命周期

maven的生命周期是抽象的,它本身并不做任何的工作。实际的工作都交由"插件"来完成。这种思想和设计模式中的模板方式。

maven内置的生命周期:

maven的每个构建步骤都可以绑定一个或多个插件行为,而且maven为大多数的构建步骤编写并绑定了默认插件。

生命周期及绑定插件
生命周期(lifecycle) 阶段(phase) plugin:goal 插件全称 任务
clean pre-clean     执行一些清理前需要完成工作
clean clean:clean maven-clean-plugin 清理上一次构建生成的文件
post-clean     执行一些清理后需要完成的工作
default validate     用于验证项目的有效性和其项目所需要的内容是否具备
initialize     初始化操作,比如创建一些构建所需要的目录等。
generate-sources     用于生成一些源代码,这些源代码在compile phase中需要使用到
process-sources     对源代码进行一些操作,例如过滤一些源代码
generate-resources

----packaging ear

ear:generate-application-xml

----packaging maven-plugin

plugin:descriptor

  生成资源文件(这些文件将被包含在最后的输入文件中)
process-resources resources:resources maven-resources-plugin 对资源文件进行处理
compile compiler:compile maven-compiler-plugin 对源代码进行编译
process-classes     对编译生成的文件进行处理
generate-test-sources     生成测试用的源代码
process-test-sources     对生成的测试源代码进行处理
generate-test-resources     生成测试用的资源文件
process-test-resources resources:testResources maven-resources-plugin 对测试用的资源文件进行处理
test-compile compiler:testCompile maven-compiler-plugin 对测试用的源代码进行编译
process-test-classes     对测试源代码编译后的文件进行处理
test surefire:test maven-surefire-plugin 进行单元测试
prepare-package     打包前置操作
package

--- Packaging ejb / ejb3 / jar / par / rar / war

ejb:ejb or ejb3:ejb3 or jar:jar or par:par or rar:rar or war:war

----packaging ear

ear:ear

----packaging maven-plugin

jar:jar and plugin:addPluginArtifactMetadata

  打包
pre-integration-test     集成测试前置操作
integration-test     集成测试
post-integration-test     集成测试后置操作
verify     运行任何检查以验证包是否有效并符合质量标准。
install

install:install

maven-install-plugin 将打包产物安装到本地maven仓库
deploy deploy:deploy maven-deploy-plugin 将打包产物安装到远程仓库
site pre-site     执行一些在生成项目站点之前需要执行的操作
site     生成项目站点
post-site site:site maven-site-plugin 执行一些在生成项目站点之前需要执行的操作
site-deploy site:deploy maven-site-plugin 将生成的站点发布到服务器上

命令行与生命周期

从命令行执行maven任务的最主要的方式就是调用maven的生命周期阶段(phase)。各个生命周期是独立的,每个生命周期指定一个阶段(也可不指定),一个生命周期的阶段是前后依赖的,此阶段前的所有阶段都会顺序执行。

maven命令格式:

mvn [options]  [<goal(s)>]   [<phase(s)>]

示例:

mvn clean

mvn test

mvn clean install

mvn clean deploy site-deploy

maven插件的目标(goal)

maven核心仅定义了抽象的生命周期阶段,具体任务由插件完成。一个插件可能有很多功能,某个功能就叫一个目标(goal)。例如:

compiler:compile, compiler:test-compile

自定义绑定

除了内置绑定外,用户可以自己指定把插件绑定到哪个阶段,配置如下:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-source-plugin</artifactId>
    <version>2.1.1</version>
    <executions>
        <execution>
            <id>attach-sources</id>
            <phase>verify</phase>
            <goals>
                <goal>jar-no-fork</goal>
            </goals>
        </execution>
    </executions>
</plugin>

命令行插件配置

可以使用maven -D参数来配置插件的参数。

mvn -install -Dmaven.test.skip=true

命令行调用插件

maven命令行:

mvn [options]  [<goal(s)>]   [<phase(s)>]

maven调用phases,可以执行绑定在生命周期的阶段的插件目标,但是有些任务不适合绑定到生命周期,可以直接从命令行调用插件。

例如:

mvn help:describe -Dplugin=compile

describe是目标(goal),help呢?help是maven-help-plugin的前缀。

插件解析机制

为了方便用户使用和配置插件,Maven不需要用户提供完整的插件坐标信息,就可以解析得到正确的插件,Maven的这一特性是一把双刃剑,虽然他简化了插件的使用和配置,可一旦插件的行为出现异常,用户就很难快速定位到问题的插件构件。例如mvn help:system这样一条命令,他到底执行了什么插件?该插件的groupId、artifactId和version分别是什么?这个构件是从哪里来的?本文就详细介绍Maven的运行机制,以让其不仅知其然,更知其所以然。

插件仓库

与依赖构件一样,插件构件同样基于坐标存储在Maven仓库中。在需要的时候,Maven会从本地仓库寻找插件,如果不存在,则从远程仓库查找。找到插件之后,再下载到本地仓库使用。

值得一提的是,Maven会区别对待依赖的远程仓库与插件的远程仓库。当Maven需要的依赖在本地仓库不存在时,他会去所配置的远程仓库查找,可是当Maven需要的插件在本地仓库不存在时,他就不会去这些远程仓库查找

不同于repositories及其repository子元素,插件的远程仓库使用pluginRepositories和pluginRepository配置。例如,Maven内置了如下的插件远程仓库配置,见下面所示。

<pluginRepositories><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><updatePolicy>never</updatePolicy></releases></pluginRepository>
</pluginRepositories>

除了pluginRepositories和pluginRepository标签不同之外,其余所有子元素表达含义与依赖远程仓库配置完全一样。我们甚至看到,这个默认插件仓库的地址就是中央仓库,他关闭了对SNAPSHOT的支持,以防止引入SNAPSHOT版本的插件而导致不稳定的构建。

一般来说,中央仓库所包含的插件完全能够满足我们的需要,因此也不需要配置其他的插件仓库。只有在很少的情况下,项目使用的插件无法在中央仓库找到,或者自己编写了插件,这个时候可以参考上述的配置,在POM或者settings.xml中加入其他的插件仓库配置。

插件的默认groupId

在POM中配置插件的时候,如果该插件是Maven的官方插件(即如果其groupId为org.apache.maven.plugins),就可以省略groupId配置,见下面所示。

    <build><plugins><artifactId>maven-compiler-plugin</artifactId><version>2.1</version><configuration><source>1.5</source><target>1.5</target></configuration></plugins></build>

上述配置中省略了maven-compiler-plugin的groupId,Maven在解析该插件的时候,会自动用默认groupId org.apache.maven.plugins补齐。

不推荐使用Maven的这一机制,虽然这么做可以省略一些配置,但这样的配置会让团队中不熟悉Maven的成员感到费解,况且能省略的配置也就仅仅一行而已。

解析插件版本

同样是为了简化插件的配置和使用,在用户没有提供插件版本的情况下,Maven会自动解析插件版本。

首先,Maven在超级POM中为所有核心插件设定了版本,超级POM是所有Maven项目的父POM,所有项目都继承这个超级POM的配置,因此,即使用户不加任何配置,Maven使用核心插件的时候,他们的版本就已经确定了。这些插件包括maven-clean-plugin、maven-compiler-plugin、maven-surefire-plugin等。

如果用户使用某个插件时没有设定版本,而这个插件又不属于核心插件的范畴,Maven就会去检查所有仓库中可用的版本,然后做出选择。以maven-compiler-plugin为例,他在中央仓库的仓库元数据为http://repol.maven.org/maven2/org/apache/maven/plugins/maven-compiler/maven-metadata.xml,其内容如下所示。

<?xml version="1.0" encoding="UTF-8" ?>
<metadata><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><versioning><latest>2.1</latest><release>2.1</release><versions><version>2.0-beta-1</version><version>2.0</version><version>2.0.1</version><version>2.0.2</version><version>2.1</version></versions></versioning>
</metadata>

Maven遍历本地仓库和所有远程插件仓库,将该路径下的仓库元数据归并后,就能计算出latest和release的值latest表示所有仓库中该构件的最新版本,而release表示最新的非快照版本。在Maven 2中,插件的版本会被解析至latest。也就是说,当用户使用某个非核心插件且没有声明版本的时候,Maven会将版本解析为所有可用仓库中的最新版本,而这个版本也可能是快照版。

当插件的版本为快照版本时,就会出现潜在的问题。Maven会基于更新策略,检查并使用快照的更新。某个插件可能昨天还用的好好的,今天就出错了,其原因就是这个快照版本的插件发生了变化。为了防止这类问题,Maven 3调整了解析机制,当插件没有声明版本的时候,不再解析至latest,而是使用release。这样就可以避免由于快照频繁更新而导致的插件行为不稳定。

依赖Maven解析插件版本其实是不推荐的做法,即使Maven 3 将版本解析到最新的非快照版,也还是会有潜在的不稳定性。例如,可能某个插件发布了一个新的版本,而这个版本的行为与之前的版本发生了变化,这种变化就可能导致项目构件失败。因此,使用插件的时候,应该一直显式的设定版本,这也解释了Maven为什么要在超级POM中为核心插件设定版本。

解析插件前缀

现在解释Maven如何根据插件前缀解析得到插件坐标。

插件前缀与groupId:artifactId是一一对应的,这种匹配关系存储在仓库元数据中。与groupId/artifactId/maven-metadata.xml不同,这里的仓库元数据为groupId/maven-metadata.xml,那么这里的groupId是什么呢?主要的插件都位于http://repol.maven.org/maven2/org/apache/maven/plugins和http://repository.codehaus.org/org/codehaus/mojo/,相应地,Maven在解析插件仓库元数据的时候,会默认使用org.apache.maven.plugins和org.codehaus.mojo两个groupId。也可以通过配置settings.xml让Maven检查其他groupId上的插件仓库元数据:

<settings><pluginGroups><pluginGroup>com.your.plugins</pluginGroup></pluginGroups>
</settings>

基于该配置,Maven就不仅仅会检查org/apache/maven/plugins/maven-metadata.xml和org/codehaus/mojo/maven-metadata.xml,还会检查com/your/plugins/maven-metadata.xml。

下面看一下插件仓库元数据的内容,见下面。

<metadata><plugins><plugin><name>Maven Clean Plugin</name><prefix>clean</prefix><artifactId>maven-clean-plugin</artifactId></plugin><plugin><name>Maven Compiler Plugin</name><prefix>compiler</prefix><artifactId>maven-compiler-plugin</artifactId></plugin><plugin><name>Maven Dependency Plugin</name><prefix>dependency</prefix><artifactId>maven-dependency-plugin</artifactId></plugin></plugins>
</metadata>

上述内容是从中央仓库的org.apache.maven.plugins.groupId下插件仓库元数据中截取的一些片段,从这段数据中就能看到maven-clean-plugin的前缀为clean,maven-compiler-plugin的前缀为compiler,maven-dependency-plugin的前缀为dependency。

当Maven解析到dependency:tree这样的命令后,他首先基于默认的groupId归并所有插件仓库的元数据org/apache/plugins/maven-metadata.xml;其次检查归并后的元数据,找到对应的artifactId为maven-dependency-plugin;然后结合当前元数据的groupId为org.apache.maven.plugins;最后解析得到version,这时就得到了完整的插件坐标。如果org/apache/maven/plugins/maven-metadata.xml,以及用户自定义的插件组。如果所有元数据中都不包含该前缀,则报错。

参考:

maven plugins 参考:http://maven.apache.org/plugins/index.html

Maven(2)--生命周期以及插件目标相关推荐

  1. Maven入门指南⑦:Maven的生命周期和插件

    Maven入门指南⑦:Maven的生命周期和插件 一个完整的项目构建过程通常包括清理.编译.测试.打包.集成测试.验证.部署等步骤,Maven从中抽取了一套完善的.易扩展的生命周期.Maven的生命周 ...

  2. maven(7)生命周期和插件

    [0]README 1)本文部分文字转自 "maven实战",旨在 review  "maven(7)生命周期和插件" 的相关知识: 2)maven 另外两个核 ...

  3. Maven的生命周期和插件

    (尊重劳动成果,转载请注明出处:https://blog.csdn.net/qq_25827845/article/details/83795622冷血之心的博客) 关注微信公众号(文强的技术小屋), ...

  4. Maven之生命周期和插件

    Maven之坐标和依赖_jerry_dyy的博客-CSDN博客 Maven之仓库_jerry_dyy的博客-CSDN博客 Maven之聚合与继承_jerry_dyy的博客-CSDN博客 Maven之生 ...

  5. Maven的生命周期与插件

    项目构建生命周期 Maven的本质是一个项目管理工具,将项目开发和管理过程抽象成一个项目对象模型(POM).Maven构建生命周期描述的是一次构建过程经历经历了多少个事件.对项目构建的生命周期划分为3 ...

  6. maven详解之生命周期与插件

    Maven是一个优秀的项目管理工具,它能够帮你管理编译.报告.文档等. Maven的生命周期: maven的生命周期是抽象的,它本身并不做任何的工作.实际的工作都交由"插件"来完成 ...

  7. maven的仓库、生命周期与插件

    一.仓库 统一存储所有Maven项目共享的构建的位置就是仓库. 仓库分为本地仓库和远程仓库.远程仓库又分为中央仓库(中央仓库是Maven核心自带的远程仓库),伺服(另一种特殊的远程仓库,为节省宽带和时 ...

  8. Maven生命周期和插件的那些事(2021版)

    前言:在日常开发中我们经常使用IDE提供的MAVEN功能,如下图所示,通过右键->run maven build的方式或者通过命令行运行maven命令的方式来对项目进行构建.在我们通过简单操作就 ...

  9. Maven读书笔记之七(生命周期和插件)

    1. 生命周期What? Maven一般能自动化执行的生命周期有清理.编译.测试.打包,部署. 2. 生命周期详解 2.1 三套生命周期 2.1.1 clean生命周期 pre-clean:清理前的准 ...

最新文章

  1. c#实例 让你明白什么是继承
  2. 探秘Hadoop生态12:分布式日志收集系统Flume
  3. java8 map reduce 分组_java8快速实现List转map 、分组、过滤等操作
  4. POSIX文件及目录管理
  5. [转帖]什么是α射线、β射线、γ射线
  6. html 图像 ppt,用HTML设置的文本和图像.ppt
  7. 依赖反转原理,IoC容器和依赖注入:第3部分
  8. wcf双工通讯遇到的问题
  9. 前端自动化构建工具之webpack入门——简单入门
  10. 什么场景下声明式事务会失效?如何解决?
  11. 2008年上半年程序员考试上午真题自我汇总
  12. python读取grd数据_ARWpost处理后的grd数据使用fortran来读取
  13. lowB三人组代码示例
  14. CSDN不友好的收藏夹
  15. 稀里糊涂的攻防世界之easyRE1
  16. OpenAPI 标准规范,了解一下?
  17. Flash时钟制作(注意:不是钟表式的)
  18. AIX7.1 安装配置 HPE 3PAR 存储驱动软件
  19. 小羊驼和你一起学习cocos2d-x与lua之六(lua编写cocos2d-x注意事项)
  20. 商品销售管理系统设计论文--毕业设计

热门文章

  1. 详解Windows开机自动运行
  2. JavaScript实现表单的分向提交
  3. JavaScript大师必须掌握的12个知识点
  4. Innodb事务和锁
  5. SQL查询数据并插入新表
  6. mySql存储过程,简单实现实例
  7. 12_02_Linux软件管理之二rpm
  8. 记录一次bug解决过程:eclipse Installed JREs 配置引出的问题
  9. COCI CONTEST #3 29.11.2014 KAMIONI
  10. Apple watch 开发指南(1) 预览