maven至今还是Java编程语言构建的事实标准,大部分项目还在使用maven来进行构建,因此了解maven内部运行的原理对定位和分析问题还是很有裨益的。本篇文章主要介绍一些maven内部运行过程中的一些基本概念,相信看完后,对那么些刚刚接触maven的读者来说maven将不再陌生。
  在具体分析项目构建的过程前,需要了解maven的一些基本概念,这些概念十分重要,请务必理解清楚后再看下文。基本概念主要有:POM,Lifecycle。这两个概念又会包含一些小的概念,下文会逐步讲解。
  POM: 注意这里的POM不是maven中构建过程使用的配置文件pom.xml,但他们之间还是有联系的。POM的全称是Project Object Model,用通俗点的话说就是对要构建的项目进行建模,将要构建的项目看成是一个对象(Object),后文就使用PO来指代这个对象。既然是一个对象,那么PO有哪些属性呢?在maven中一个项目都是用一个唯一的坐标(coordinate)来表示,坐标由groupId, artifactId, version, classifier, type这五部分组成。这样来说PO应该也要具备坐标属性。另外一方面,一个项目肯定不是孤立存在的,可能依赖于其他的一些项目,那么也就是说PO应该具备dependencies这个属性,用来表示其所依赖的外部项目。我们可以尝试一下用Java代码来描述下PO这个对象:

class PO{private String groupId;private String artifactId;private String version;private String classifier;private String type;private Set<PO> dependencies;
}

我们知道XML的表达能力是很强大的,一个Java中的对象是可以用XML来描述,例如一个上面定义的PO对象则可以用下面的XML来描述(表达有不规范之处,理解其中的含义即可):

<PO><groupId></groupId><artifactId></artifactId><version></version><classifier><classifier><type></type><dependencies><PO></PO><PO></PO>...</dependencies>
</PO>

是不是好像和什么有点类似?对,就是pom.xml。pom.xml就是PO对象的XML描述。上面的PO定义还不完整,我们继续看下PO还有什么其他的属性。我们知道在Java中类是可以继承的,一个对象在创建的时候会同时创建其父类对象,类似的,PO对象也有其父对象,用parent属性来表示,并且PO对象会继承其父对象的所有属性。另外一方面,一个项目可能根据不同职责分为多个模块(module),所有模块其实也就是一个单独的项目,只不过这些项目会使用其父对象的一些属性来进行构建。我们将这些新的属性加到PO的定义中去:

lass PO{private String groupId;private String artifactId;private String version;private String classifier;private String type;private Set<PO> dependencies;private PO parent;private Set<PO> modules;
}

再将这个定义用XML语言表示一下:

<PO><parent></parent><groupId></groupId><artifactId></artifactId><version></version><classifier><classifier><type></type><dependencies><PO></PO><PO></PO>...</dependencies><modules>...</modules>
</PO>

是不是越来越像pom.xml了?对,这就是pom.xml的由来。再说一遍:pom.xml就是PO对象的XML描述。到此为止,相信你再看pom.xml文件时,会有一个全新的认识。

  上面说的这些PO属性是项目的一些固有属性,到目前为止,我们还没有涉及项目的构建过程。构建过程对应的是PO对象的build属性,那么你应该马上想到,在pom.xml中就是<build>元素中的内容。这里就有引入maven中第二个核心概念:Lifecycle。Lifecycle直译过来就是生命周期。我们平常会接触到哪些周期呢?一年中春夏秋冬就是一个周期。一个周期中可能分为多个阶段,比如这里的春夏秋冬。在maven中一个构建过程就对应一个Lifecycle,这个Lifecycle也分为多个阶段,每个阶段叫做phase。你可能会问,那这个Lifecycle中包含多少个phase呢?一个标准的构建Lifecycle包含了如下的phase:

validate: 用于验证项目的有效性和其项目所需要的内容是否具备
initialize:初始化操作,比如创建一些构建所需要的目录等。
generate-sources:用于生成一些源代码,这些源代码在compile phase中需要使用到
process-sources:对源代码进行一些操作,例如过滤一些源代码
generate-resources:生成资源文件(这些文件将被包含在最后的输入文件中)
process-resources:对资源文件进行处理
compile:对源代码进行编译
process-classes:对编译生成的文件进行处理
generate-test-sources:生成测试用的源代码
process-test-sources:对生成的测试源代码进行处理
generate-test-resources:生成测试用的资源文件
process-test-resources:对测试用的资源文件进行处理
test-compile:对测试用的源代码进行编译
process-test-classes:对测试源代码编译后的文件进行处理
test:进行单元测试
prepare-package:打包前置操作
package:打包
pre-integration-test:集成测试前置操作
integration-test:集成测试
post-integration-test:集成测试后置操作
install:将打包产物安装到本地maven仓库
deploy:将打包产物安装到远程仓库

在maven中,你执行任何一个phase时,maven会将其之前的phase都执行。例如 mvn install,那么maven会将deploy之外的所有phase按照他们出现的顺序一次执行。
  Lifecycle还牵涉到另外一个非常重要的概念:goal。注意上面Lifecycle的定义,也就是说maven为程序的构建定义了一套规范流程:第一步需要validate,第二步需要initialize... ... compile,test,package,... ... install,deploy,但是并没有定义每一个phase具体应该如何操作。这里的phase的作用有点类似于Java语言中的接口,只协商了一个契约,但并没有定义具体的动作。比如说compile这个phase定义了在构建流程中需要经过编译这个阶段,但没有定义应该怎么编译(编译的输入是什么?用什么编译javac/gcc?)。这里具体的动作就是由goal来定义,一个goal在maven中就是一个Mojo(Maven old java object)。Mojo抽象类中定义了一个execute()方法,一个goal的具体动作就是在execute()方法中实现。实现的Mojo类应该放在哪里呢?答案是maven plugin里,所谓的plugin其实也就是一个maven项目,只不过这个项目会引用maven的一些API,plugin项目也具备maven坐标。
  在执行具体的构建时,我们需要为lifecycle的每个phase都绑定一个goal,这样才能够在每个步骤执行一些具体的动作。比如在lifecycle中有个compile phase规定了构建的流程需要经过编译这个步骤,而maven-compile-plugin这个plugin有个compile goal就是用javac来将源文件编译为class文件的,我们需要做的就是将compile这个phase和maven-compile-plugin中的compile这个goal进行绑定,这样就可以实现Java源代码的编译了。有点绕,多看几遍。那么有人就会问,在哪里绑定呢?答案是在pom.xml<build>元素中配置即可。例如:

<build>
<plugins><plugin><artifactId>maven-myquery-plugin</artifactId><version>1.0</version><executions><execution><id>execution1</id><phase>test</phase><configuration><url>http://www.foo.com/query</url><timeout>10</timeout><options><option>one</option><option>two</option><option>three</option></options></configuration><goals><goal>query</goal></goals></execution></executions></plugin>
</plugins>
</build>

就将maven-myquery-plugin中的query这个goal绑定到了test这个phase,后续在maven执行到test phase时就会执行query goal。还有有人可能会问,我都没有指定Java源文件的位置,编译啥?这就引出了maven的design principle。在maven中,有一个非常著名的principle就是convention over configuration(约定优于配置)。这一点和ant有非常大的区别,例如使用ant来进行编译时,我们需要指定源文件的位置,输出文件的位置,javac的位置,classpath... ...在maven中这些都是不需要,若没有手动配置,maven默认从<项目根目录>/src/main/java这个目录去查找Java源文件,编译后的class文件会保存在<项目根目录>/target/classes目录。在maven中,所有的PO都有一个根对象,就是Super POM。Super POM中定义了所有的默认的配置项。Super POM对应的pom.xml文件可以在maven安装目录下lib/maven-model-builder-3.0.3.jar:org/apache/maven/model/pom-4.0.0.xml中找到。用一张图来表示maven Lifecycle,phase,goal之间的关系:

文/zlwen(简书作者)
原文链接:http://www.jianshu.com/p/0fb5e3fb704d
 

转载于:https://www.cnblogs.com/billyu/p/6046163.html

maven内部运行原理解析相关推荐

  1. spark启动的worker节点是localhost_Spark大数据在线培训:Spark运行原理解析

    在大数据技术框架当中,Spark是继Hadoop之后的又一代表性框架,也是学习大数据当中必学的重点技术框架.在这些年的发展当中,Spark所占据的市场地位,也在不断拓展.今天的Spark大数据在线培训 ...

  2. 孙鑫VC++LESSON1:Windows程序内部运行原理

    视频链接:https://www.bilibili.com/video/BV1Ts411f7fw/?spm_id_from=333.337.search-card.all.click&vd_s ...

  3. Windows程序内部运行原理

    Windows程序内部运行原理   为了理解Visual C++应用程序开发过程,先要理解Windows程序的运行机制.因为 Visual C++是 Windows 开发语言,需要明白在 Window ...

  4. Windows程序内部运行原理(2)

    Windows程序内部运行原理   为了理解Visual C++应用程序开发过程,先要理解Windows程序的运行机制.因为 Visual C++是 Windows 开发语言,需要明白在 Window ...

  5. JavaScript 运行原理解析

    参考 JavaScript 运行原理解析 [先读这一篇] https://juejin.cn/post/6844903551009816589 JavaScript is one of the 3 l ...

  6. JavaScript运行原理解析

    写在前面的话: 发现使用了那么长时间的Javascript,但是对其运行原理还是不清晰,今天特意总结一下,把大神们的理论和自己的总结都记录到下面: 1. 什么是JavaScript解析引擎? 简单地说 ...

  7. Vue.js 运行原理解析、vue源码剖析

    Vue.js 运行机制全局概览 全局概览 这一节笔者将为大家介绍一下 Vue.js 内部的整个流程,希望能让大家对全局有一个整体的印象,然后我们再来逐个模块进行讲解.从来没有了解过 Vue.js 实现 ...

  8. iis运行原理 Asp.Net详解IIS内部运行原理

    本章节主要讲IIS和 管道内部如何处理客户端Http请求,会较多的以代码的形式讲述,让大家对HttpApplication.HttpHandler.HttpApplicationFactory.Pag ...

  9. 计算机硬件系统 — 冯诺依曼体系结构运行原理解析

    目录 文章目录 目录 计算机系统 计算机硬件系统(冯诺依曼体系结构) PC 主机硬件 CPU(中央处理器) CPU 的组成部分 CPU 总线 控制器单元 运算器单元 寄存器组 超线程与多核架构 三级高 ...

最新文章

  1. 安装、连接MS SQL Server 2000的问题
  2. 查看target/classes/.../dao/文件夹下,发现只有mapper的class文件,而没有xml文件 的解决方法。
  3. 【Windows 逆向】OD 调试器工具 ( 显示模块窗口 | 显示记录窗口 | 显示内存窗口 | 显示线程 | 显示句柄 | 显示 CPU | 多窗口界面 )
  4. Java 洛谷 P1014 Cantor表
  5. hdu 2833(Floyd + dp)
  6. python 逗号作用 语句间_Python中逗号的三种作用
  7. RobotFramework自动化框架—robot文件中调用自定义库
  8. 【面向对象设计原则】之开闭原则(OCP)
  9. 物件导向比面向对象更准确
  10. ie浏览器调用本地文件无反应_ie上传附件没有反应怎么办_解决ie浏览器上传附件没有反应的方法...
  11. YouTube和Twitch上的流媒体之间有何区别?
  12. 如何用计算机将图片整成手绘画,【新手教程】如何将手绘作品转变成电子档,并让其更像“作品”?...
  13. 简单的外汇市场赚钱方法
  14. 【职场思考】没听过的22条技术大牛的建议
  15. (15.1.5.2)当抗日神剧遇上轻小说(我已笑抽)
  16. 调音台docker教程_Docker实例教程[超详细](一)
  17. JSCanvas画板
  18. 基于分数阶傅里叶变换的人脸识别(王亚星)
  19. 为什么你最后哪都没去
  20. 12306抢票 JAVA客户端

热门文章

  1. abaqus生成adams柔性体_Abaqus和STAR-CCM+流固耦合
  2. R的数据可视化,各种图表,常用统计量计算
  3. R包实践:lubridate 处理时间数据
  4. 16bit随机数生成matlab,关于matlab生成随机数
  5. 无法识别依赖属性_设计模式起步-UML学习 - 认识UML类图(依赖)
  6. ios textview间距_iOS开发之UITextView,设置textView的行间距及placeholder
  7. 质量属性效用树_知识之森-数据化你的quot;知识树”
  8. C陷阱与缺陷阅读笔记(上)
  9. 孙鑫-MFC笔记九--菜单编程
  10. python自动化运维工程师面试题_运维面试题(含答案)