mirror鏡像和repository遠程倉庫
mirror就是鏡像,主要提供一個方便切換遠程倉庫地址的途徑。
比如,上班的時候在公司,用電信的網(wǎng)絡,連的是電信的倉庫。
回到家后,是聯(lián)通的網(wǎng)絡,我想連聯(lián)通的倉庫,就可以通過mirror配置,統(tǒng)一把我工程里的倉庫地址都改成聯(lián)通的,而不用到具體工程配置文件里一個一個地改地址。
《maven實戰(zhàn)》里面解釋的鏡像:


mirrorof的官方文檔解釋
https://maven.apache.org/guides/mini/guide-mirror-settings.html
可以理解為,mirrorof就是鏡像規(guī)則。這個規(guī)則,將鏡像mirror(setting.xml的設置)和遠程倉庫repository(pom.xml的repository設置)關聯(lián)起來。哪個遠程倉庫被哪個鏡像所替代。
如果還是沒能理解,可以看看這兩篇博客。
maven的setting配置文件中mirror和repository的區(qū)別
- ==如果maven setting.xml中配置了鏡像mirror , 而鏡像mirror配置里mirrorof的規(guī)則,匹配到目標倉庫時 ,
maven認為目標倉庫被鏡像了, 不會再去被鏡像倉庫下載依賴jar包, 而是直接去鏡像倉庫下載。即maven里面設置的repository會被setting.xml里面的mirror所屏蔽。== - <mirrorof></mirrorof>的值為匹配repository倉庫的id。也可以使用高級配置,如通配符*,否定符!。
<mirror>
<id>aliyun-maven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>repotest</mirrorOf>
</mirror>
鏡像配置的規(guī)則 <mirrorOf>repotest</mirrorOf> 匹配到目標倉庫 <id>repotest</id>,所以maven認為目標倉庫repotest被鏡像了, 不再去https://repo.maven.apache.org/maven2/地址下載jar包,而是去鏡像倉庫http://maven.aliyun.com/nexus/content/groups/public/下載jar包。
<repositories>
<repository>
<id>repotest</id>
<url>https://repo.maven.apache.org/maven2/</url>
</repository>
</repositories>
我們通過下面例子去理解鏡像mirror和倉庫repository和mirrorof的含義
默認中央倉庫
先把setting.xml里面的mirror配置去掉,保持<mirrors></mirrors>節(jié)點為空,然后一步一步開始實踐,了解這三個的含義。
# 在pom.xml配置以下內(nèi)容:
<repositories>
<repository>
<id>cloudera</id>
<url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.6.0-dad1-cdh5.14.2</version>
</dependency>
</dependencies>
- 可以從idea的解析maven依賴的順序,觀察出:先去cloudera倉庫找這個jar包。

- 發(fā)現(xiàn)在cloudera倉庫沒找這個jar包。所以去默認中央倉庫去找這個jar包。

從上面這個例子,我們可以這么理解,默認情況下,maven下面的pom.xml的中央倉庫,缺省了模板倉庫id為central,url為maven中央倉庫url:https://repo.maven.apache.org/maven2/。
# 默認中央倉庫
<repositories>
<repository>
<id>central</id>
<url>https://repo.maven.apache.org/maven2/</url>
</repository>
</repositories>
修改默認中央倉庫地址
我們可以在pom.xml,設置一個id為central和url來覆蓋缺省 id = central的url。
<repositories>
<repository>
<id>central</id>
<url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>
</repositories>
然后下載mysql驅動,此時發(fā)現(xiàn),下載mysql驅動失敗。因為默認中央倉庫的url被重寫成cloudera公司的目標倉庫。但cloudera公司自己搭建的倉庫里面并沒有這個jar包。所以pom.xml找不到這個jar包。

倉庫的優(yōu)先級
先從repository找出所有id的名字,看看他們有沒有被setting.xml配置的mirror的mirrorof規(guī)則所匹配(即被鏡像到),如果有,將repository的url地址改成mirror配置的url,替換完地址后。再依次檢索repositorys下面所有的repository下載相應的jar。
例子1:
<mirrorOf>central</mirrorOf>
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
<repositories>
<repository>
<id>central</id>
<url>https://repo.maven.apache.org/maven2/</url>
</repository>
<repository>
<id>cloudera</id>
<url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>
</repositories>
- 鏡像url替換后會變成下面所示:
<repositories>
<repository>
<id>central</id>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</repository>
<repository>
<id>cloudera</id>
<url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>
</repositories>
- 然后依次從central倉庫,尋找jar包,如果找不到則到cloudera倉庫尋找jar。
- 可以通過hadoop-client這個只有cloudera倉庫有的jar,而阿里云沒有。去看看maven尋找jar包的過程。
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.6.0-mr1-cdh5.14.2</version>
</dependency>
</dependencies>
例子2:
<mirrorOf>central</mirrorOf>加上<mirrorOf>*</mirrorOf>
pom.xml的設置:
<repositories>
<repository>
<id>cloudera</id>
<url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>
<repository>
<id>central</id>
<url>https://arepository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>
</repositories>
加上setting.xml的設置:
<mirror>
<id>aliyun-maven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
<mirror>
<id>central-Repository</id>
<name>Maven central Repository</name>
<url>https://repo1.maven.org/maven2/</url>
<mirrorOf>*</mirrorOf>
</mirror>
# <mirrorOf>central</mirrorOf> 匹配到遠程倉庫 <id>central</id>,所以遠程倉url替換成mirror的url;
# 因為<id>central</id>已經(jīng)被mirror的url替換了,就不再鏡像了;
# <mirrorOf>*</mirrorOf> 替換 <id>cloudera</id>的url。
最終的目標倉庫:
<repositories>
<repository>
<id>cloudera</id>
<url>https://repo1.maven.org/maven2</url>
</repository>
<repository>
<id>central</id>
<url>http://maven.aliyun.com/nexus/content/groups/public//</url>
</repository>
</repositories>
所以一般來說setting.xml只需要配置一個central的鏡像規(guī)則就好了,一般就是阿里云就好了,然后需要其他遠程倉庫,就手動在pom.xml里面加上repository,但不是這個第三方的倉庫就不要把repository的id寫成central。不然就被鏡像的規(guī)則匹配到了,url被替換成阿里云的了。
setting.xml里面的mirror,可以寫多個,但mirrorof的規(guī)則要從匹配范圍小到大寫。同時寫多個mirrorof的內(nèi)容為central的意義為0,因為只有其中第一個mirror生效。
鏡像搭配遠程倉庫
一般setting.xml內(nèi)容為:
<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>
假設某個jar包,阿里云鏡像沒有的jar,把可以下載這個jar包的遠程倉庫,補充到pom.xml就好了。如:
<repositories>
<repository>
<id>cloudera</id>
<url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>
</repositories>
有時公司搭建了內(nèi)網(wǎng),只能從私服下載jar包,這時maven項目,pom.xml的repository都是各個私服的url。
(假設都可以在阿里云倉庫找到這些jar包,記住這里是假設所有的可以在阿里云的https://maven.aliyun.com/repository/central下載到?。。。┗氐郊依?,可以將阿里云的鏡像規(guī)則設置成 <mirrorOf>*</mirrorOf>,則強制所有遠程倉庫都到這個鏡像下載url。解決了不需要修改pom.xml。
<mirrors>
<mirror>
<id>aliyun-maven</id>
<name>aliyun maven</name>
<url>https://maven.aliyun.com/repository/central</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
如果項目里面有些jar包在https://maven.aliyun.com/repository/central倉庫找不到,那么setting.xml的mirrorOf 設置成*就不合適了。應該將 <url>https://maven.aliyun.com/repository/central</url>設置成<mirrorOf>center</mirrorOf>,然后未找到的jar包再設置<mirrorOf>repository_name</mirrorOf>實現(xiàn)代理。
一般項目里面,我們應該如何正確設置repositories和國內(nèi)鏡像呢
當我們項目里面需要設置第三方的倉庫時,如cloudera的倉庫,那么建議<repositories>第一個先寫上<repository>倉庫的id為center,再寫第三方的repository倉庫的id和url。這樣項目里的jar的下載順序是從center的中央倉庫(如果我們配置了國內(nèi)鏡像則從國內(nèi)倉庫)下載,如果找不到再輪到這個第三方的倉庫。避免很多jar包在第三方倉庫找不到然后再去center的下載,很慢,我們應該讓依賴首先去中央倉庫查找,找不到再去第三方倉庫找。
下面是我的配置
pom.xml
<repositories>
<repository>
<id>central</id>
<url>https://maven.aliyun.com/repository/central</url>
</repository>
<repository>
<id>cloudera</id>
<url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>
</repositories>
setting.xml
<mirror>
<id>aliyunmaven</id>
<mirrorOf>center</mirrorOf>
<name>阿里云公共倉庫</name>
<url>https://maven.aliyun.com/repository/central</url>
</mirror>
這個配置,下載依賴的流程為:
- 將repository中id為center的url替換成setting.xml中mirrorOf為center的url。(因為repository中id為center和setting.xml中mirrorOf為center所匹配,所以會將mirror的id為aliyunmaven的url替換掉pom里面id為center的repository。)
- 下載依賴時,先從central倉庫下載,如果找不到則從cloudera的repository倉庫查找。
有同學會有疑問:
pom.xml 這樣寫可不可以?
<repositories>
<repository>
<id>cloudera</id>
<url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>
</repositories>
答案是可以的,但是如果seting.xml里面沒有配置國內(nèi)鏡像,那么從cloudera倉庫里面查找鏡像,找不到鏡像,則從默認id為center的中央倉庫地址https://repo1.maven.org/maven2查找鏡像,下載速度會很慢,且下載順序是先cloudera倉庫再center倉庫,這樣下載速度會比較慢,防止有些人沒有在setting.xml設置國內(nèi)中央倉庫的鏡像,還是建議第一個repository的id為center,url為國內(nèi)的鏡像,一舉兩得。