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版本號最新一次歸檔的組件。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM