Maven 配置文件 proxy、server、repository、mirror 節點筆記

原由

寫這篇文章起源於同事一個問題,大概就是進入我們公司以後,會統一發 maven 的 settings.xml 文件,直接覆蓋 maven 自帶的就能夠正常使用。而後他想知道其中爲何既要配 repository、server 還要配 mirror?這些配置屬性含義是什麼?這幾者之間是什麼關係?配了多個 repository 以後查找 jar 的前後順序是什麼?結合 mirror 又會怎麼查找?php

雖然以前有把 Maven 這塊做過系統的筆記(Maven 實戰小結),但真的問我這塊的時候,才發現遺漏了,如今補一下。html

proxy、server、repository、mirror 理解

  • proxy 是 maven 所在服務器不能直接訪問外網時須要設置的代理服務(不經常使用)
  • server 是當 maven 須要要打包代碼上傳到私服時,設置私服的鑑權信息,帳號+密碼
  • repository 是 maven 去下載 jar 包的倉庫
  • mirror 是用於替代 repository 鏡像地址

proxy、server 很好理解,因此重點在於 repository、mirror 二者。那麼如何區分二者呢?apache

這裏用私服(內部倉庫)和鏡像(mirror)來作解釋:服務器

  • internal repository(私服) 是指在局域網內部搭建的 repository,跟 central repository, jboss repository 等的區別僅僅在於其URL是一個內部網址
  • mirror(鏡像) 則至關於一個代理,會攔截去指定的遠程 repository 下載構件的請求,而後從本身這裏找出構件回送給客戶端。配置 mirror 的目的通常是出於網速考慮

能夠看出,私服和 mirror 是兩碼事。前者自己是一個 repository,能夠用來提供公司內部的 maven 構件;然後者自己並非 repository,它只是遠程 repository 的網絡加速器網絡

不過,不少 internal repository 搭建工具每每也提供 mirror 服務,好比 Nexus 就可讓同一個 URL,既用做 internal repository,又使它成爲全部 repository 的 mirrormaven

若是倉庫X能夠提供倉庫Y存儲的全部內容,那麼就能夠認爲X是Y的一個鏡像。換句話說,任何一個能夠從倉庫Y得到的構件,都胡夠從它的鏡像中獲取。舉個例子,http://maven.net.cn/content/groups/public/ 是中央倉庫 http://repo1.maven.org/maven2/ 在中國的鏡像,因爲地理位置的因素,該鏡像每每可以提供比中央倉庫更快的速度。ide

mirror 的配置

一個 mirror 節點能夠對應一個或多個 repository 節點,由 mirrorOf 中的所填的值控制。工具

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
  ...
  <mirrors>
    <mirror>
      <id>planetmirror.com</id>
      <name>PlanetMirror Australia</name>
      <url>http://downloads.planetmirror.com/pub/maven2</url>
      <mirrorOf>central</mirrorOf>
    </mirror>
  </mirrors>
  ...
</settings>
複製代碼
  • id 屬性,mirror 標識(暫時沒發現其餘地方會引用這個值)
  • name 屬性,名字,描述
  • url 屬性,鏡像地址
  • mirrorOf 屬性,該鏡像對應的 repository 的 ID(在 Profiles-Repositories-repository-id 中定義)。 例如,要指向 Maven 中央存儲庫(repo.maven.apache.org/maven2/)的鏡像… central。 還可使用更高級的映射,例如repo1,repo2或* ,!inhouse。此值必須與鏡像 ID 不相同。

如下是使用網易的鏡像,來替代中央的倉庫的配置樣例:post

<mirrors>
     <mirror>
      <id>maven.163.com</id>
      <name>maven mirror in China</name>
      <url>http://mirrors.163.com/maven/repository/maven-public/</url>
      <mirrorOf>central</mirrorOf>
    </mirror>
</mirrors>
複製代碼

在實際使用過程當中,會有以下的不標準配置:ui

<mirrors>
     <mirror>
      <id>maven.163.com</id>
      <name>maven mirror in China1</name>
      <url>http://mirrors.163.com/maven/repository/maven-public/</url>
      <mirrorOf>central</mirrorOf>
    </mirror>
</mirrors>
<mirrors>
    <mirror>
      <id>aliyun.com</id>
      <name>maven mirror in China2</name>
      <mirrorOf>central</mirrorOf>
      <url>https://maven.aliyun.com/repository/public</url>
    </mirror>
</mirrors>
複製代碼

將兩個不一樣的鏡像同時指向 central 倉庫,這種方式 maven 只會選取第一個匹配的鏡像,也就是 maven.163.com 這個,第二個永遠不會生效。官網解釋以下:

Note that there can be at most one mirror for a given repository. In other words, you cannot map a single repository to a group of mirrors that all define the same value. Maven will not aggregate the mirrors but simply picks the first match. If you want to provide a combined view of several repositories, use a repository manager instead.

當配置的是對 central 倉庫的鏡像時,不須要配置 repository 節點信息(由於 maven 默認已經配了)。若是須要了解的更加詳細的內容,查看官網 mirror 配置介紹:guide-mirror-settings

repository 的配置

repository 節點必須做爲 repositorys 的子節點存在,而 repositorys 節點又必須做爲 profiles 節點的子節點存在。

<profiles>
    <profile>
        <id>nexus</id>
        <repositories>
            <!-- 公司私服配置 -->
            <repository>
                <id>you-internal-repos</id>
                <url>you-internal-repos-address</url>
                <releases>
                    <enabled>true</enabled>
                    <updatePolicy>always</updatePolicy>
                    <checksumPolicy>warn</checksumPolicy>
                </releases>
                <snapshots>
                    <enabled>true</enabled>
                    <updatePolicy>always</updatePolicy>
                    <checksumPolicy>warn</checksumPolicy>
                </snapshots>
            </repository>
            <!-- 阿里雲私服配置 -->
            <repository>
                <id>aliyun-repos</id>
                <url>https://maven.aliyun.com/nexus/content/groups/public/</url>
                <releases>
                    <enabled>true</enabled>
                </releases>
                <snapshots>
                    <enabled>true</enabled>
                </snapshots>
            </repository>
        </repositories>
    </profile>
</profiles>

<!-- 默認生效 -->
<activeProfiles>
    <activeProfile>nexus</activeProfile>
</activeProfiles>
複製代碼

mirror、repository 的查找順序

  • 當一個 repository 存在 mirror 時,Maven 查找 jar 時永遠使用的是 mirror 配置的地址。
  • 當一個 repository 不存在 mirror 時,按照在 repositories 節點中定義的前後順序。先定義,先查找。

第一點不用驗證,就是 Maven 的機制。第二點是本身驗證的結果,再也不累述驗證過程,大概就是刪除某個本地已經存在的 jar 再次打包,使用命令 mvn package -X 打包並輸出詳細調試日誌,查找 jar 包的名字關鍵字,看第一次去哪一個遠程倉庫查,調換遠程倉庫定義順序,再次嘗試,便可獲得結果。

配置實例

如下是一個用阿里雲鏡像代替中央倉庫的配置文件樣例:

<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <localRepository>你的本地倉庫地址</localRepository>
  <pluginGroups></pluginGroups>
  <proxies></proxies>
  <servers></servers>
  <mirrors>
    <mirror>
      <id>nexus-aliyun</id>
      <name>Nexus aliyun</name>
      <mirrorOf>central</mirrorOf>
      <url>https://maven.aliyun.com/repository/public</url>
    </mirror>
    <mirror>
      <id>nexus-mine</id>
      <name>Nexus mine</name>
      <mirrorOf>*</mirrorOf>
      <url>http://xx.xx.xx.xx/nexus/content/groups/public</url>
    </mirror>
  </mirrors>
</settings>
複製代碼

參考

相關文章
相關標籤/搜索