寫這篇文章起源於同事一個問題,大概就是進入我們公司以後,會統一發 maven 的 settings.xml 文件,直接覆蓋 maven 自帶的就能夠正常使用。而後他想知道其中爲何既要配 repository、server 還要配 mirror?這些配置屬性含義是什麼?這幾者之間是什麼關係?配了多個 repository 以後查找 jar 的前後順序是什麼?結合 mirror 又會怎麼查找?php
雖然以前有把 Maven 這塊做過系統的筆記(Maven 實戰小結),但真的問我這塊的時候,才發現遺漏了,如今補一下。html
proxy、server 很好理解,因此重點在於 repository、mirror 二者。那麼如何區分二者呢?apache
這裏用私服(內部倉庫)和鏡像(mirror)來作解釋:服務器
能夠看出,私服和 mirror 是兩碼事。前者自己是一個 repository,能夠用來提供公司內部的 maven 構件;然後者自己並非 repository,它只是遠程 repository 的網絡加速器。網絡
不過,不少 internal repository 搭建工具每每也提供 mirror 服務,好比 Nexus 就可讓同一個 URL,既用做 internal repository,又使它成爲全部 repository 的 mirror。maven
若是倉庫X能夠提供倉庫Y存儲的全部內容,那麼就能夠認爲X是Y的一個鏡像。換句話說,任何一個能夠從倉庫Y得到的構件,都胡夠從它的鏡像中獲取。舉個例子,http://maven.net.cn/content/groups/public/
是中央倉庫 http://repo1.maven.org/maven2/
在中國的鏡像,因爲地理位置的因素,該鏡像每每可以提供比中央倉庫更快的速度。ide
一個 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>
複製代碼
如下是使用網易的鏡像,來替代中央的倉庫的配置樣例: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 節點必須做爲 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>
複製代碼
第一點不用驗證,就是 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>
複製代碼