zoukankan      html  css  js  c++  java
  • Maven学习(3)-依赖管理-POM文件中依赖的jar包下载过程详解

    参考来源:

    https://www.liupeng.mobi/archives/1816 (包含有依赖下载过程详解)

    https://blog.csdn.net/chenpuzhen/article/details/84201811

    https://blog.csdn.net/pinebud55/article/details/78667299

    https://www.cnblogs.com/songcuiting/p/8783750.html

    一、Maven中坐标概念                                                                                       

    Maven对依赖进行统一管理,通过定义项目的依赖关系,Maven从仓库查找和下载依赖的组件(jar包、war包、pom文件等等)。那么Maven如何来唯一标识一个依赖组件呢?这就涉及到Maven中坐标的概念。

    Maven中的坐标包含:groupId 、artifactId、version 三个元素:

    • groupId:项目所在组,一般是组织或公司。
    • artifactId:是当前项目在组中的唯一ID。
    • version:表示版本。Release表示发布版本,SNAPSHOT表示快照,表示此项目还在开发中,不稳定。

    Maven在定义依赖时,需要指定如上的坐标。如:以pom.xml中的junit为例:

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-starter</artifactId>
      <version>2.1.1</version>
    </dependency>

    通过如上依赖组件的坐标定义,Maven从仓库中按照 “groupId”“artifactId”"version" 的路径来下载依赖组件包。

    二、通过greoupId和ArtifactId唯一定位到一个项目,但是项目过程中伴随着多次编译和发布,Maven中是如何管理version的?

    详细的关于Maven中版本管理的细节,见对应章节。此处仅做大概描述,为后续解释Maven下载依赖组件过程做铺垫。

    Maven中的项目版本分为Release版本和Snapshot版本。

    Release版本为发布的稳定版本,可以理解为一个版本号只归档、发布一次。版本号一般采用类似1.0、1.1的方式。

    Snapshot版本为开发过程中的迭代版本,对于同一版本号,开发过程中可以多次编译、归档。版本号一般采用"版本号-SNAPSHOT"的格式,比如1.0-SNAPSHOT。

    三、基于以上坐标、版本机制,我们看看依赖组件在仓库中是如何归档的?                                                

    以Mytest项目为例,其在远程仓库、本地仓库归档内容可以如下:

    1、在远程仓库的归档(Realse仓库)

    |--1.0.0

        |--Mytest-1.0.0.pom

        |--Mytest-1.0.0.pom.asc

        |--Mytest-1.0.0.jar

        |--Mytest-1.0.0.jar.asc

    |--1.0.1

        |--Mytest-1.0.1.pom

        |--Mytest-1.0.1.pom.asc

        |--Mytest-1.0.1.jar

        |--Mytest-1.0.1.jar.asc

    |--maven-metadata.xml

    如上,其项目归档根目录下,以版本号为目录来归档不同的release版本。

    1)每个release版本下,包含jar项目包、及.pom文件。其中.pom文件记录的是项目本次版本的pom定义,内含本项目坐标、依赖关系、插件信息、构建过程定义等。

    2)项目归档根目录下,还有一个maven-metadata.xml文件,这个文件干啥用呢?

          maven-metadata.xml内容样例如下:

      <?xml version="1.0" encoding="UTF-8"?>
      <metadata>
        <groupId>com.AAAAA</groupId>
        <artifactId>Mytest</artifactId>
        <version>1.1.</version>
        <versioning>
          <latest>1.1.1</latest>
          <release>1.1.1</release>
          <versions>
            <version>1.0.0</version>
            <version>1.0.1</version>
          </versions>
          <lastUpdated>20191221041500</lastUpdated>
        </versioning>
      </metadata>

    如上样例所示,maven-metadata.xml中实际上记录的是项目的历史版本过程。

    2、在远程仓库的归档(Snapshot仓库)

    |--1.0.0-SNAPSHOT

        |--Mytest-1.0.0-20191215.090030.pom

        |--Mytest-1.0.0-20191215.090030.jar

        |--Mytest-1.0.0-20191216.160005.pom

        |--Mytest-1.0.0-20191216.160005.jar

        |--maven-metadata.xml

    |--1.0.1-SNAPSHOT

        |--Mytest-1.0.1-20191220.100021.pom

        |--Mytest-1.0.1-20191220.100021.jar

        |--Mytest-1.0.1-20191220.164405.pom

        |--Mytest-1.0.1-20191220.164405.jar

        |--maven-metadata.xml

    |--maven-metadata.xml

    如上,其项目归档根目录下,以版本号为目录来归档不同的Snapshot版本。和Release仓库文件目录结构的差异如下:

    1)版本目录(如1.0.1-SNAPSHOT目录)下多了个maven-metadata.xml文件。样例:

           <?xml version="1.0" encoding="UTF-8"?>
      <metadata modelVersion="1.1.0">
        <groupId>com.AAAAA</groupId>
        <artifactId>Mytest</artifactId>
        <version>1.0.1-SNAPSHOT</version>
        <versioning>
          <snapshot>
            <timestamp>20191220.164405</timestamp>
            <buildNumber>34</buildNumber>
          </snapshot>
          <lastUpdated>20191220164405</lastUpdated>
          <snapshotVersions>
            <snapshotVersion>
               <extension>jar</extension>
              <value>1.0.1-20191220.100021</value>
              <updated>20191220100021</updated>
            </snapshotVersion>
            <snapshotVersion>
              <extension>pom</extension>
              <value>1.0.1-20191220.164405</value>
              <updated>20191220164405</updated>
            </snapshotVersion>
          </snapshotVersions>
        </versioning>
      </metadata>

          因为Maven中同一个Snopshot版本是可以多次编译、归档的,所以具体某个Snopshot版本内的mave-matedata.xml记录了本Snapshot版本的多次归档的历史记录。本文件中的历史记录采用 版本号+时间戳 方式。

    2)项目Snapshot仓库 根目录 下的maven-matedata.xml样例如下:   

      <?xml version="1.0" encoding="UTF-8"?>
      <metadata>
        <groupId>com.fyklocal</groupId>
        <artifactId>demologinserver</artifactId>
        <version>1.0.1-SNAPSHOT</version>
        <versioning>
          <versions>
            <version>1.0.0-SNAPSHOT</version>
            <version>1.0.1-SNAPSHOT</version>
          </versions>
          <lastUpdated>20200123083452</lastUpdated>
        </versioning>
      </metadata>

           项目根目录下成这个maven-metadata.xml记录的是本项目SNAPSHOT版本的历史记录。

    3、项目在本地仓库中的目录

    |--1.0.0

        |--Mytest-1.0.0.pom

        |--Mytest-1.0.0.pom.asc

        |--Mytest-1.0.0.jar

        |--Mytest-1.0.0.jar.asc

    |--1.0.0-SNAPSHOT

        |--Mytest-1.0.0-SNAPSHOT.pom

        |--Mytest-1.0.0-SNAPSHOT.jar

        |--maven-metadata-local.xml

    |--1.0.1

        |--Mytest-1.0.1.pom

        |--Mytest-1.0.1.pom.asc

        |--Mytest-1.0.1.jar

        |--Mytest-1.0.1.jar.asc

    |--1.0.1-SNAPSHOT

        |--Mytest-1.0.1-SNAPSHOT.pom

        |--Mytest-1.0.1-SNAPSHOT.jar

        |--maven-metadata-local.xml

    |--maven-metadata-local.xml

    和远程仓相比:

    1)maven-metadata.xml文件本地命名为meven-metadata-local.xml

    2)根目录的maven-metadata-local.xml中同时记录了 Release 和 SNOAPSHOT 版本的历史。

      <?xml version="1.0" encoding="UTF-8"?>
      <metadata>
        <groupId>com.AAAAA</groupId>
        <artifactId>Mytest</artifactId>
        <version>1.0.1</version>
        <versioning>
          <latest>1.0.1</latest>
          <release>1.0.1</release>
          <versions>
            <version>1.0.0-SNAPSHOT</version>
            <version>1.0.0</version>
            <version>1.0.1-SNAPSHOT</version>
            <version>1.0.1</version>
          </versions>
          <lastUpdated>20191221041500</lastUpdated>
        </versioning>
      </metadata>

    3)SNAPSHOT版本目录下仅记录最新一次SNOTSHOT版本信息(未从远程仓下载,则是本地最后一次mvn install的;从远程仓下载,则是远程仓上本SNAPSHOT版本归档的最后一次)。

         .pom文件和.jar文件由于只保存最新一份,直接以SNAPSHOT命名,不需要以时间戳命名。

         如:1.0.1-SNAPSHOT/maven-metadata-local.xml 文件内容如下。和远程仓相比,版本也直接使用1.0.1-SNAPSHOT,不需要用时间戳命名。

      <?xml version="1.0" encoding="UTF-8"?>
      <metadata modelVersion="1.1.0">
        <groupId>com.fyklocal</groupId>
        <artifactId>demologinserver</artifactId>
        <version>1.0.1-SNAPSHOT</version>
        <versioning>
          <snapshot>
            <localCopy>true</localCopy>
          </snapshot>
          <lastUpdated>20191220164405</lastUpdated>
          <snapshotVersions>
            <snapshotVersion>
              <extension>jar</extension>
              <value>1.0.1-SNAPSHOT</value>
              <updated>20191220100021</updated>
            </snapshotVersion>
            <snapshotVersion>
              <extension>pom</extension>
              <value>1.0.1-SNAPSHOT</value>
              <updated>20191220164405</updated>
            </snapshotVersion>
          </snapshotVersions>
        </versioning>
      </metadata>

    总结:

    1).pom文件是对应每个版本包一份,用于记录当前版本包的POM信息。

    2)maven-metadata.xml用于记录项目构建历史记录。下载依赖组件使,用于做版本和时间比较。

    四、那么Maven从中央仓库、远程仓库下载依赖组件时,到底是如何根据版本工作的呢?                                                

    阅读本章节前,请先阅读本文前面部分关于远程仓库、本地仓库maven-metadata.xml、.pom文件的说明。

    如第(一)章节所说,Maven中依赖通过groupId 、artifactId、version 三个元素组成的坐标定位,在pom.xml定义的依赖也包含这三个元素。

    <dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-starter</artifactId>
      <version>2.1.1</version>
    </dependency>

    在执行mvn命令时,会根据pom.xml的定义解析依赖,并下载。

    (1)当指定的依赖组件版本 为 具体某个Release版本(如:2.1、2.1.1等)

       Maven会现在本地仓库中根据 {groupId}/{artifactId} 路径来查找对应版本的组件是否存在?

        ■ 如果本地仓库存在,直接使用。

        ■ 如果本地仓库不存在,则先从中央仓库按照 {groupId}/{artifactId}/maven-metadata.xml 查找是否存在对应版本的组件。如果存在:

           (A)合并中央仓库/远程仓库中 groupId/artifactId/ 下的maven-metadata.xml到本地仓库的{groupId}/{artifactId}/maven-metadata-local.xml中。

           (B)并下载 {groupId}/{artifactId}/{version}下的组件到本地仓库。

        ■ 如果中央仓库也不存在,逐个查找支持Release版本的远程仓库,先检查远程仓库的 <updatePolicy>配置的更新频率是否达到,如果更新次数没达到,则继续同中央仓库的(A)、(B)步骤。

    (2)当指定的依赖组件版本 为 “RELEASE” (表示获取最新的Release版本。不推荐)

      Maven会检查中央仓库,及所有支持Release版本的远程仓库、检查<updatePolicy>配置的更新频率是否达到。对于所有满足下载条件的仓库:

       ■ 从中央仓库、所有远程仓库中 下载 {groupId}/{artifactId}/maven-metadata.xml到本地仓库,并和本地仓库{groupId}/{artifactId}/maven-metadata-local.xml合并。合并后,得到最新Release版本的值。

       ■ 如果本地仓库中的 组件 就是最新版本,则直接使用。

       ■ 如果本地仓库中的 组件 不是最新版本,则根据最新版本号,从 中央仓库/远程仓库 下载组件到本地仓库。

    (3)当指定的依赖组件版本 为 具体某个SNAPSHOT版本(如:2.1-SNAPSHOT等)

      Maven会检查所有支持Snapshot版本的远程仓库,检查<updatePolicy>配置的更新频率是否达到。对于更新次数没达到所有远程仓库:

       ■ 从所有远程仓库中 下载 {groupId}/{artifactId}/2.1-SNAPSHOT/maven-metadata.xml到本地仓库,并和本地仓库maven-metadata-local.xml合并,根据SNAPSHOT的时间戳版本号,获取2.1-SNAPSHOT对应版最新一次信息。(SNAPSHOT同一版本,可以构建归档多次,通过时间说格式的版本号区分,如:Mytest-1.0.1-20191220.100021.jar。)

       ■ 下载2.1-SNAPSHOT版本对应的最新组件到本地仓库的 {groupId}/{artifactId}/2.1-SNAPSHOT/目录下,并把2.1-SNAPSHOT的时间戳版本 变更 为-SNAPSHOT版本(如:Mytest-1.0.1-20191220.100021.jar 变更为 Mytest-1.0.1-SNAPSHOT.jar)。

       ■ 更新本地仓库{groupId}/{artifactId}/maven-metadata-local.xml、{groupId}/{artifactId}/2.1-SNAPSHOT/maven-metadata-local.xml中对应的时间戳等信息。

    (4)当指定的依赖组件版本 为 “SNAPSHOT” (表示获取最新的SNAPSHOT版本)

      Maven会检查所有支持Snapshot版本的远程仓库、检查<updatePolicy>配置的更新频率是否达到。对于所有满足下载条件的仓库:

       ■ 从所有远程仓库中 下载 {groupId}/{artifactId}/maven-metadata.xml到本地仓库,并和本地仓库{groupId}/{artifactId}/maven-metadata-local.xml合并。合并后,得到最新Snapshot版本号。

       ■ 同(3)中步骤,根据最新的Snapshot版本号,获取此Snapshot版本号最新一次归档的组件。

  • 相关阅读:
    【WCSF】DynamicMethod 的类型所有者无效解决方案
    关于微软企业库查询语句db.ExecuteNonQuery(cmd)返回1的问题
    ASP.NET 如何取得 Request URL 的各個部分
    CSS模拟HTML滚动条
    JavaScript Madness不同的浏览器的keycode比较
    手机身份证IP地址开放接口
    sql添加数据后返回受影响行数据
    jquery下removeClass(“oldClassName”).addClass("newClassName")的问题
    躺着看书!这是所谓 "躺着就能长智慧" 吗?
    在web开发中使用dynsrc被McAfee报木马病毒的解决
  • 原文地址:https://www.cnblogs.com/yickel/p/12230839.html
Copyright © 2011-2022 走看看