maven倉庫筆記

一、倉庫

1.什麼是Maven倉庫

在Maven世界中,任何一個依賴、插件或者項目構建的輸出,都可以稱爲構件

Maven可以在某個位置統一存儲所有 Maven項目共享的構件,這個統一的位置就是倉庫。實際的 Maven項目將不再各自存儲其依賴文件,它們只需要聲明這些依賴的座標,在需要的時候, Maven會自動根據座標找到倉庫中的構件,並使用它們。

2.倉庫的佈局

任何一個構件都有其唯一的座標,根據這個座標可以定義其在倉庫中的唯一存儲路徑,這便是Maven的倉庫佈局方式。

該路徑與座標的大致對應關係爲:groupId / artifactId / version / artifactId - version.packaging

3.倉庫的分類

3.1 依賴搜索機制

在這裏插入圖片描述

對於Maven來說,倉庫只分爲兩類:本地倉庫和遠程倉庫。

依賴搜索機制:

當 Maven根據座標尋找構件的時候,

  • 它首先會查看本地倉庫,如果本地倉庫存在此構件,則直接使用;
  • 如果本地倉庫不存在此構件,或者需要查看是否有更新的構件版本, Maven就會去遠程倉庫查找,發現需要的構件之後,下載到本地倉庫再使用。
  • 如果本地倉庫和遠程倉庫都沒有需要的構件, Maven就會報錯。

3.2 本地倉庫

一個構件只有在本地倉庫中之後,才能由其他 Maven 項目使用。

那麼構件如何進入到本地倉庫中呢?

  • 遠程下載:最常見的是依賴Maven從遠程倉庫下載到本地倉庫中。
  • 本地安裝:還有一種常見的情況是,將本地項目的構件安裝到 Maven倉庫中。

3.3 遠程倉庫

對於Maven來說,每個用戶只有一個本地倉庫,但可以配置訪問很多遠程倉庫。

3.3.1 中央倉庫

中央倉庫是Maven核心自帶的遠程倉庫,它包含了絕大部分開源的構件。在默認配置下,當本地倉庫沒有 Maven需要的構件的時候,它就會嘗試從中央倉庫下載。

  • 由於最原始的本地倉庫是空的,Maven必須知道至少一個可用的遠程倉庫,才能在執行 Maven命令的時候下載到需要的構件。中央倉庫就是這樣一個默認的遠程倉庫, Maven的安裝文件自帶了中央倉庫的配置。
  • 在$M2_HOME/lib/ maven-model-builder-3.0. jar 中 org/apache/maven/model/pom-4.0.0.xml 文件中有如下配置(即中央倉庫的配置):
   <repositories>
     <repository>
       <id>central</id>
       <name>Central Repository</name>
       <url>https://repo.maven.apache.org/maven2</url>
       <layout>default</layout>
       <snapshots>
         <enabled>false</enabled>
       </snapshots>
     </repository>
   </repositories>

3.3.2 私服

私服是一種特殊的遠程倉庫,它是架設在局域網內的倉庫服務,私服代理廣域網上的遠程倉庫,供局域網內的
Maven用戶使用。

  • 當 Maven需要下載構件的時候,它從私服請求,如果私服上不存在該構件,則從外部的遠程倉庫下載,緩存在私服上之後,再爲 Maven的下載請求提供服務。
  • 此外,一些無法從外部倉庫下載到的構件也能從本地上傳到私服上供大家使用,

4.遠程倉庫的配置

4.1 遠程倉庫的配置

  <repositories>
    <repository>
      <id>jboss</id>
      <name>Jboss Repository</name>
      <url>http://repository.jboss.com/maven2</url>
      <releases>
        <enabled>true</enabled>
      </releases>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
    <layout>default</layout>
  </repositories>

在repositories元素下,可以使用 repository子元素聲明一個或者多個遠程倉庫。

  • id : 倉庫的唯一標識。任何一個倉庫聲明的id必須是唯一的,尤其需要注意的是, Maven自帶的中央倉庫使用的 id爲 central,如果其他的倉庫聲明也使用該 id,就會覆蓋中央倉庫的配置。
  • url : 指定倉庫的地址。
  • releases : 若enable值爲true,則表示開啓此倉庫的 release 版本的下載支持。
  • snapshots : 若enable值爲true,則表示開啓此倉庫的 snapshot 版本的下載支持。
  • layout : 若爲default,則表示倉庫的佈局是Maven 2及 Maven 3的默認佈局,

4.2 遠程倉庫的認證

大部分遠程倉庫無須認證就可以訪問,但有時候出於安全方面的考慮,我們需要提供認證信息才能訪問一些遠程倉庫。

  • 認證信息必須配置在 settings.xml 文件中:

配置認證信息和配置倉庫信息不同,倉庫信息可以直接配置在POM文件中,但是認證信息必須配置在 settings.xml文件中。這是因爲 POM往往是被提交到代碼倉庫中供所有成員訪問的,而 settings.xml一般只放在本機。因此,在 settings.xml中配置認證信息更爲安全。

 <server>
   <id>repo-id</id>
   <username>repo-usernamer</username>
   <password>repo-password</password>
 </server>

Maven使用 settings.xml 文件中的 servers元素及其 server子元素配置倉庫認證信息:

  • id : 倉庫id,必須與POM(或settings.xml)中需要認證的 repository元素的 id完全一致。換句話說,正是這個 id將認證信息與倉庫配置聯繫在了一起。

4.3 部署至遠程倉庫

私服的一大作用是部署第三方構件,包括組織內部生成的構件以及一些無法從外部倉庫直接獲取的構件。

無論是日常開發中生成的構件,還是正式版本發佈的構件,都需要部署到倉庫中,供其他團隊成員使用。

    <distributionManagement>
        <repository>
            <id>proj-releases</id>
            <name>Proj Release Repositories</name>
            <url>http://nexus.saas.hand-china.com/content/repositories/proj-releases</url>
        </repository>

        <snapshotRepository>
            <id>proj-snapshots</id>
            <name>Proj Snapshot Repositories</name>
            <url>http://nexus.saas.hand-china.com/content/repositories/proj-snapshots</url>
        </snapshotRepository>
    </distributionManagement>

distributionManagement包含 repository 和 snapshotRepository 子元素,前者表示發佈版本構件的倉庫,後者表示快照版本的倉庫。

  • id : 倉庫的唯一標識
  • name : 爲了可讀性
  • url : 指定倉庫地址
  • 往遠程倉庫部署構件的時候,往往需要認證。配置認證的方式已在第4.2節中詳細闡述,簡而言之,就是需要在 settings.xml中創建一個 server元素,其 id與倉庫的 id匹配,並配置正確的認證信息。
  • 不論從遠程倉庫下載構件,還是部署構件至遠程倉庫,當需要認證的時候,配置的方式是一樣的。

配置正確後,在命令行運行 mvn clean deploy, Maven就會將項目構建輸出的構件部署到配置對應的遠程倉庫,如果項目當前的版本是快照版本,則部署到快照版本倉庫地址,否則就部署到發佈版本倉庫地址。

5.從倉庫解析依賴的機制

當本地倉庫沒有依賴構件的時候,Maven會自動從遠程倉庫下載;當依賴版本爲快照版本的時候,Maven會自動找到最新的快照。這背後的依賴解析機制可以概括如下:

1)當依賴的範圍是system的時候,Maven直接從本地文件系統解析構件。

2)根據依賴座標計算倉庫路徑後,嘗試直接從本地倉庫尋找構件,如果發現相應構件,則解析成功。

3)在本地倉庫不存在相應構件的情況下,如果依賴的版本是顯式的發佈版本構件,如1.2、2.1-beta-1等,則遍歷所有的遠程倉庫,發現後,下載並解析使用。

4)如果依賴的版本是RELEASE或者LATEST,則基於更新策略讀取所有遠程倉庫的元數據groupId/artifactId/maven-metadata.xml,將其與本地倉庫的對應元數據合併後,計算出RELEASE或者LATEST真實的值,然後基於這個真實的值檢查本地和遠程倉庫,如步驟2)和3)。

5)如果依賴的版本是SNAPSHOT,則基於更新策略讀取所有遠程倉庫的元數據groupId/artifactId/version/maven-metadata.xml,將其與本地倉庫的對應元數據合併後,得到最新快照版本的值,然後基於該值檢查本地倉庫,或者從遠程倉庫下載。

6)如果最後解析得到的構件版本是時間戳格式的快照,如1.4.1-20091104.121450-121,則複製其時間戳格式的文件至非時間戳格式,如SNAPSHOT,並使用該非時間戳格式的構件。

當依賴的版本不明晰的時候,如RELEASE、LATEST和SNAPSHOT,Maven就需要基於更新遠程倉庫的更新策略來檢查更新。在第6.4節提到的倉庫配置中,有一些配置與此有關:

  • 首先是 <releases><enabled><snapshots><enabled>,只有倉庫開啓了對於發佈版本的支持時,才能訪問該倉庫的發佈版本構件信息,對於快照版本也是同理;
  • 其次要注意的是 <releases><snapshots>的子元素 <updatePolicy>,該元素配置了檢查更新的頻率,每日檢查更新、永遠檢查更新、從不檢查更新、自定義時間間隔檢查更新等。
  • 最後,用戶還可以從命令行加入參數-U,強制檢查更新,使用參數後,Maven就會忽略 <updatePolicy> 的配置。

當Maven檢查完更新策略,並決定檢查依賴更新的時候,就需要檢查倉庫元數據maven-metadata.xml。

倉庫元數據並不是永遠正確的,有時候當用戶發現無法解析某些構件,或者解析得到錯誤構件的時候,就有可能是出現了倉庫元數據錯誤,這時就需要手工地,或者使用工具(如Nexus)對其進行修復。

6.鏡像

如果倉庫X可以提供倉庫Y存儲的所有內容,那麼就可以認爲X是Y的一個鏡像。

6.1 配置中央倉庫鏡像

<settings>
...
  <mirrors>
    <mirror>
      <id>aliyun-maven</id>
      <name>aliyun maven</name>
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
      <mirrorOf>central</mirrorOf>
    </mirror>
  </mirrors>
...
</settings>
  • id : 鏡像ID
  • name : 鏡像名稱,爲了可讀性
  • url : 鏡像倉庫地址
  • mirrorOf : 誰的鏡像。<mirrorOf> 的值爲central,表示配置爲中央倉庫的鏡像,任何對於中央倉庫的請求都會轉至該鏡像,用戶也可以使用同樣的方法配置其他倉庫的鏡像。
  • 三個元素id、name、url與一般倉庫配置無異,表示該鏡像倉庫的唯一標識符、名稱以及地址。

類似地,如果該鏡像需要認證,也可以基於該id配置倉庫認證。

  • mirrorOf 節點還支持更加高級的配置:
    • <mirrorOf>*</mirrorOf>:匹配所有遠程倉庫。
    • <mirrorOf>external:*</mirrorOf>:匹配所有遠程倉庫,使用localhost的除外,使用file://協議的除外。也就是說,匹配所有不在本機上的遠程倉庫。
    • <mirrorOf>repo1,repo2</mirrorOf>:匹配倉庫repo1和repo2,使用逗號分隔多個遠程倉庫。
    • <mirrorOf>*,!repo1</mirrorOf>:匹配所有遠程倉庫,repo1除外,使用感嘆號將倉庫從匹配中排除。

需要注意的是:

由於鏡像倉庫完全屏蔽了被鏡像倉庫,當鏡像倉庫不穩定或者停止服務的時候,Maven仍將無法訪問被鏡像倉庫,因而將無法下載構件。

6.3 使用私服作爲鏡像

由於私服可以代理任何外部的公共倉庫(包括中央倉庫),因此,對於組織內部的Maven用戶來說,使用一個私服地址就等於使用了所有需要的外部倉庫,這可以將配置集中到私服,從而簡化Maven本身的配置。

在這種情況下,任何需要的構件都可以從私服獲得,私服就是所有倉庫的鏡像。

<settings>
...
  <mirrors>
    <mirror>
      <id>nexus-ray</id>
      <name>my maven nexus</name>
      <url>http://192.168.12.101/nexus/content/groups/public/</url>
      <mirrorOf>*</mirrorOf>
    </mirror>
  </mirrors>
...
</settings>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章