maven deploy plugin_(转)maven内部运行原理解析(一)

2023-11-08

原文来源于:http://www.jianshu.com/p/0fb5e3fb704d

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的定义中去:

class 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之间的关系:


Lifecyle-phase-plugin-goal关系图


到此为止,相信对于POM, pom.xml,Lifecycle, phase, goal这些概念应该十分清楚了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

maven deploy plugin_(转)maven内部运行原理解析(一) 的相关文章

随机推荐

  • 特征工程(1)--特征工程是什么?

    机器学习领域的大神Andrew Ng 吴恩达 老师曾说 Coming up with features is difficult time consuming requires expert knowledge Applied machin
  • 乐高编程机器人编程有什么区别

    乐高编程机器人编程有什么区别 一直以来家长们对于孩子的学习重视程度可谓是相当的大 很多的家长会给孩子选择一些能够让孩子适应社会发展的课程 就拿现在很多的家长想要孩子去学习机器人编程的课程来说 有的家长对于乐高编程机器人编程有什么区别并不清楚
  • 【Xgplayer】xgplayer基本使用

    文章目录 xgplayer简介 xgplayer官网 Xgplayer VS VideoJs xgplayer下载 播放器组件 使用播放器 效果图 推荐 xgplayer简介 开发团队 字节跳动 字节跳动出品 必属精品 xgplayer是一
  • VS2022编译GDAL库报错: LINK : error LNK2001: 无法解析的外部符号 _OSRValidate _OGR_G_GetPointCount _OGRRegisterAll

    目录 场景复现 解决方案 场景复现 使用VS2022的Native Tools command prompt for 2022工具编译GDAL库时 报 LINK error LNK2001 无法解析的外部符号 OSRValidate OGR
  • Pytorch入门实战(5):基于nn.Transformer实现机器翻译(英译汉)

    使用Google Colab运行 open In Colab 源码地址 文章目录 本文涉及知识点 本文内容 环境配置 数据预处理 文本分词与构造词典 Dataset and Dataloader 模型构建 模型训练 模型推理 本文涉及知识点
  • 数据库并发控制 事务调度 可串行调度

    所谓并发操作 是指在多用户共享的系统中 许多用户可能同时对同一数据进行操作 所带来的问题是数据的不一致性 具体表现为 丢失更新 不可重复读 读脏数据 1 事务调度 1 1 串行调度 Serial Schedule 是指多个事务依序串行执行
  • 华为手机上的网上邻居怎么用_HUAWEI Mate 8 网络邻居 使用教程

    本帖最后由 爱奔跑的蜗牛 于 2016 1 19 23 54 编辑 有根数据线 手机连接电脑传输管理文件算不上什么秘密 但总有那么一两天 忘记带数据线 又急需拷贝电脑文件到手机上 除了问别人借数据线 难道就不能 自力更生 了吗 当然不是 拥
  • 【华为OD机试真题 python】通信误码【2022 Q4

    题目描述 通信误码 信号传播过程中会出现一些误码 不同的数字表示不同的误码ID 取值范围为1 65535 用一个数组记录误码出现的情况 每个误码出现的次数代表误码频度 请找出记录中包含频度最高误码的最小子数组长度 输入描述 误码总数目 取值
  • Python编程的注意事项

    目录 一 异常处理 1 精细化地捕获异常 2 finally 块中的资源清理 3 抛出自定义异常 二 类的继承 1 不要过度使用继承 2 了解多重继承的问题 三 垃圾回收与内存管理 1 对象引用计数的概念 2 循环引用的问题 Python
  • Kubernetes中的PV和PVC

    K8s引入了一组叫作Persistent Volume Claim PVC 和Persistent Volume PV 的API对象 大大降低了用户声明和使用持久化Volume的门槛 在Pod的Volumes中 只要声明类型是persist
  • [1080]idea import引用报错

    从GIT上拉下代码后 出现这种情况 类正常 但是import是浅灰色 引用类有红色警告 代码中所有的引用都报错 重启idea 无效 删除引用的类与被引用的类中的代码 无效 重新加载maven 无效 最后 清理缓存后 恢复正常 File gt
  • 硬件系统工程师宝典(29)-----应用DC/DC要注意什么?

    各位同学大家好 欢迎继续做客电子工程学习圈 今天我们继续来讲这本书 硬件系统工程师宝典 上篇我们说到使用LDO时 除了要考虑输入 输出电压外 还要注意压差 最大输出电流等 今天我们来讲讲DC DC的应用分析 DC DC分类 将一个不受控的输
  • 台式电脑重装系统失败怎么办

    当大家使用一键重装系统软件给自己电脑重装系统的时候 都可能会遇到一些故障问题造成台式电脑重装系统失败的情况发生 那么大家遇到台式电脑重装系统失败怎么办呢 现在小编就教下大家相关的方法教程 大家一起来看看吧 工具 原料 系统版本 window
  • 【开源之美】nanomsg(2) :req/rep 模式

    req rep 模式显然就是类似http的应答模式 在某些基于短连接的进程间通讯方式上可以很方便的使用 下面我们举个例子 服务端 demo ifndef NANOMSGUTIL H define NANOMSGUTIL H include
  • [已解决] 数据库连接问题Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionExcept...

    我在学习SSM框架做一个小demo 时遇到了这个问题 具体的报错时 Error querying database Cause org springframework jdbc CannotGetJdbcConnectionExceptio
  • 真假难辨?来看看华为云区块链怎么搞定

    怎么证明你是你 你的合同是真合同 被骗 防被骗 怎么证明自己的证据是真实的 跑路 人间蒸发 怎么还原事实维护自己的合法产权 云 5G的普遍应用与流量平面化 促使数字化资产内容爆发式增长 数字合同 知识版权 书籍 视频 音乐 个人信息等在流通
  • FFT频谱分析原理

    FFT频谱分析原理 采样定理 采样频率要大于信号频率的两倍 N个采样点经过FFT变换后得到N个点的以复数形式记录的FFT结果 假设采样频率为Fs 采样点数为N 那么FFT运算的结果就是N个复数 或N个点 每一个复数就对应着一个频率值以及该频
  • 内外网电脑远程桌面教程(win10)

    内网远程桌面连接 1 要远程的用户必须有密码 设置本机固定ip 自行百度 2 关闭防火墙与修改 在 控制面板 Windows 防火墙 启用或关闭Windows防火墙 3 打开远程桌面设置 在 桌面 计算机 上右击 打开 属性 远程设置 然后
  • linux 的configure --prefix=/

    linux configure prefix 是 编译指定程序存放路径 不指定prefix 可执行文件默认shu放在 usr local bin 库文件默认放在 usr local lib 配置文件默认放在 usr local etc 其它
  • maven deploy plugin_(转)maven内部运行原理解析(一)

    原文来源于 http www jianshu com p 0fb5e3fb704d maven至今还是Java编程语言构建的事实标准 大部分项目还在使用maven来进行构建 因此了解maven内部运行的原理对定位和分析问题还是很有裨益的 本