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. laravel5.5 不能正常自动回复的问题
  2. ubuntu的SSH的安装和免密码登陆
  3. java接口测试工具_接口测试基础了解篇
  4. Day3--js--可恶之变量声明提升大法.。。
  5. pmp每日三题(2022年3月4日)
  6. #UnityTips# 2017.11.14
  7. PIT和TestNG突变测试简介
  8. Bootstrap研究1-精巧的网格布局系统
  9. 超级详细备注的代码:Python帮助您高效通过英语六级考试
  10. [转]linux常用命令学习总结(超详细)
  11. 理解JavaScript的宏微任务
  12. React redux
  13. 2020中国联通软件研究院秋招笔试编程题
  14. access如何保存小数点后_如何设置石材雕刻机原点及断电后怎么保存原点坐标?...
  15. conda 环境复制
  16. 打造数字化软件工厂 —— 一站式 DevOps 平台全景解读
  17. 2021面试题——微信小程序面试题
  18. CPU峰值性能计算方法
  19. 继明哥的否定之后,java泰又出新作!明哥接码!
  20. MATLAB虚拟现实

热门文章

  1. PowerDesigner的基本使用
  2. 类似pyinstaller_pyinstaller安装与使用——那些我踩过的坑
  3. python的时间序列,Python时间序列
  4. idea 自动生成mybaits_如何让idea自动创建mybatis配置文件?
  5. 2022年考研数据结构_3 栈和队列
  6. mysql8.0数据回滚_大企业数据库服务首选!AliSQL这几大企业级功能你不可不知
  7. 卷积云神经网络_有卷积云的北京天空好美!是不是还有池化云?全连接云?
  8. python 手机自动化操作_Python自动化办公之word操作
  9. lepus监控oracle数据库_数据库监控软件Lepus之修改admin密码
  10. java 数据包含_java – 包含大量数据库表的通用实现