Maven 倉(cāng)庫(kù)
在之前的章節(jié)中,我們分別介紹了 Maven 中的工程對(duì)象模型(POM)以及 Maven 的依賴管理,但是,這個(gè)時(shí)候,我們勢(shì)必會(huì)有一個(gè)疑問(wèn),當(dāng)我找到一個(gè)依賴的坐標(biāo)后,只需要將該坐標(biāo)放入到我項(xiàng)目的 POM 文件當(dāng)中,這個(gè)依賴就算是被引入了,那這個(gè)依賴是從哪里來(lái)的呢?
在本節(jié)中,我們就帶著這個(gè)疑問(wèn)來(lái)學(xué)習(xí) Maven 的倉(cāng)庫(kù),了解如何使用 Maven 倉(cāng)庫(kù)。
1. 什么是 Maven 倉(cāng)庫(kù)
我們先想象一下,如果沒(méi)有 Maven,我們?cè)陂_(kāi)發(fā)不同項(xiàng)目的時(shí)候,如果需要依賴同一個(gè) jar 包,那么就需要分別在兩個(gè)不同項(xiàng)目中將這個(gè) jar 包引入進(jìn)去,對(duì)于一個(gè)程序員來(lái)說(shuō),這樣的做法顯然是不合理的,不僅需要我們手動(dòng)到處復(fù)制,而且會(huì)多占用我們的磁盤(pán)空間。
那這個(gè)時(shí)候,Maven 倉(cāng)庫(kù)就出現(xiàn)了。我們通常把依賴稱(chēng)為構(gòu)件,每一個(gè)構(gòu)件都有自己唯一的坐標(biāo),基于這種模式,我們就可以把這些構(gòu)件存放在一個(gè)指定的位置–Maven倉(cāng)庫(kù)當(dāng)中,然后通過(guò)其坐標(biāo)來(lái)尋找該構(gòu)件。
在我們學(xué)習(xí)或者實(shí)際開(kāi)發(fā)過(guò)程中,只需要在我們的項(xiàng)目當(dāng)中聲明依賴的坐標(biāo),在項(xiàng)目編譯的或者打包的過(guò)程中,Maven 會(huì)自動(dòng)從倉(cāng)庫(kù)中去尋找該構(gòu)件,這樣就不需要我們?cè)诒镜卮鎯?chǔ)這個(gè)依賴了。
2. 倉(cāng)庫(kù)的分類(lèi)
對(duì)于 Maven 來(lái)說(shuō),主要的倉(cāng)庫(kù)種類(lèi)可以分為兩種,一種是本地倉(cāng)庫(kù),另一種是遠(yuǎn)程倉(cāng)庫(kù)。而在遠(yuǎn)程倉(cāng)庫(kù)當(dāng)中呢,又可以分為中央倉(cāng)庫(kù),私服和其他的公共倉(cāng)庫(kù)。
2.1 本地倉(cāng)庫(kù)
在我們聲明的 MAVEN_HOME 路徑下,找到 conf\settings.xml
,其中可以看到 Maven 的本地倉(cāng)庫(kù)路徑配置:
從上圖我們可以看到,Maven 的默認(rèn)本地倉(cāng)庫(kù)路徑是在 ${user.home}/.m2/repository
,我們?yōu)榱朔奖銓⑵湫薷臑榱?D:\repo
。
2.2 中央倉(cāng)庫(kù)
Maven 中默認(rèn)配置了中央倉(cāng)庫(kù),我們可以在超級(jí) POM 里面找到對(duì)應(yīng)的配置。
這個(gè)倉(cāng)庫(kù)是由 Maven 社區(qū)來(lái)維護(hù)的,里面存放了絕大多數(shù)開(kāi)源軟件的包,并且是作為 Maven 的默認(rèn)配置,不需要開(kāi)發(fā)者額外配置。另外為了方便查詢,還提供了一個(gè)查詢地址,開(kāi)發(fā)者可以通過(guò)這個(gè)地址更快的搜索需要構(gòu)件的坐標(biāo)。
2.3 其他遠(yuǎn)程倉(cāng)庫(kù)
有了中央倉(cāng)庫(kù),我們?yōu)槭裁催€需要其他的遠(yuǎn)程倉(cāng)庫(kù)呢?
- 我們要找的構(gòu)件可能不存在于中央倉(cāng)庫(kù)中;
- 由于某些原因,訪問(wèn)中央倉(cāng)庫(kù)的速度相對(duì)較慢。
這種時(shí)候,我們就可以選擇一個(gè)使用起來(lái)相對(duì)方便的遠(yuǎn)程倉(cāng)庫(kù)來(lái)配置,大大提高了我們的開(kāi)發(fā)效率。
國(guó)內(nèi)常用的 Maven 倉(cāng)庫(kù):
-
阿里云鏡像:
<mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>central</mirrorOf> </mirror>
-
阿里巴巴鏡像:
<mirror> <id>ibiblio</id> <mirrorOf>central</mirrorOf> <name>Human Readable Name for this Mirror.</name> <url>http://mirrors.ibiblio.org/pub/mirrors/maven2/</url> </mirror>
-
repo2 鏡像:
<mirror> <id>repo2</id> <mirrorOf>central</mirrorOf> <name>Human Readable Name for this Mirror.</name> <url>http://repo2.maven.org/maven2/</url> </mirror>
我們可以將對(duì)應(yīng)的倉(cāng)庫(kù)的鏡像配置到 settings.xml 文件中的 mirrors 節(jié)點(diǎn)中即可。如下圖所示,我們配置了阿里云的鏡像。
2.4 私服
私服也是屬于遠(yuǎn)程倉(cāng)庫(kù)的一種,相對(duì)公共倉(cāng)庫(kù)而言屬于某個(gè)公司或者某個(gè)開(kāi)發(fā)團(tuán)隊(duì)私有的遠(yuǎn)程倉(cāng)庫(kù)。通常部署在某個(gè)局域網(wǎng)內(nèi),提供局域網(wǎng)的內(nèi)部用戶使用。
那私服有什么好處呢?
- 更快的下載速度:由于是局域網(wǎng)內(nèi)部的請(qǐng)求,因此下載構(gòu)件的速度是可以保證的;
- 更穩(wěn)定的構(gòu)建:想象一下,如果我們依賴某個(gè)外部的遠(yuǎn)程倉(cāng)庫(kù),當(dāng)這個(gè)倉(cāng)庫(kù)出現(xiàn)不可能用的情況,哪怕是網(wǎng)絡(luò)的波動(dòng),都有可能會(huì)造成我們的構(gòu)建失?。?/li>
- 部署第三方構(gòu)件:如果一個(gè)公司使用了微服務(wù)架構(gòu),那么公共倉(cāng)庫(kù)是肯定沒(méi)辦法獲取這些私有的構(gòu)件的。
當(dāng)我們需要一個(gè)構(gòu)件的時(shí)候,Maven 會(huì)先去請(qǐng)求私服,如果發(fā)現(xiàn)私服中,沒(méi)有該構(gòu)件,那么就會(huì)去配置了的遠(yuǎn)程倉(cāng)庫(kù)中尋找,并且緩存到我們的私服中,為后續(xù)的下載請(qǐng)求提供服務(wù)。
3. Maven 的依賴解析順序
我們知道了 Maven 通過(guò)坐標(biāo)去倉(cāng)庫(kù)中尋找對(duì)應(yīng)的構(gòu)件,那么這個(gè)機(jī)制的原理是怎么樣的呢?
Maven 在尋找需要的依賴的時(shí)候,會(huì)遵照下面的順序:
- 如果構(gòu)件的依賴范圍是 system,Maven 會(huì)直接從本地的文件系統(tǒng)來(lái)解析該構(gòu)件;
- 根據(jù)配置的依賴坐標(biāo),在本地倉(cāng)庫(kù)中尋找該構(gòu)件,如果能夠搜索到,則解析成功;
- 如果本地倉(cāng)庫(kù)沒(méi)有搜索到,那么就會(huì)去已經(jīng)配置了的遠(yuǎn)程倉(cāng)庫(kù)中搜索該構(gòu)件,搜索到后,下載到本地倉(cāng)庫(kù)中,提供項(xiàng)目使用;
- 如果依賴的版本是 RELEASE 或 LATEST,那么就會(huì)根據(jù)更新策略去讀取所有遠(yuǎn)程倉(cāng)庫(kù)中的元數(shù)據(jù)信息(groupId/artifactId/maven-metadata.xml),并且與本地倉(cāng)庫(kù)中對(duì)應(yīng)的元數(shù)據(jù)合并后,計(jì)算出真實(shí)值,再將其下載到本地倉(cāng)庫(kù)中;
- 如果依賴的版本是 SNAPSHOT,那么就會(huì)根據(jù)更新策略去讀取所有遠(yuǎn)程倉(cāng)庫(kù)中的元數(shù)據(jù)信息(groupId/artifactId/version/maven-metadata.xml),并且與本地倉(cāng)庫(kù)中對(duì)應(yīng)的元數(shù)據(jù)信息合并后,得到最新的快照版本值,根據(jù)這個(gè)值去尋找對(duì)應(yīng)的依賴;
- 解析出的快照版本一般是帶有時(shí)間戳的,下載下來(lái)后,會(huì)將該時(shí)間戳刪掉,以無(wú)時(shí)間戳的形式來(lái)使用。
4. 小結(jié)
在本節(jié)中,我們介紹了什么是 Maven 倉(cāng)庫(kù),主要的倉(cāng)庫(kù)分類(lèi)以及不同倉(cāng)庫(kù)的特點(diǎn)。最后我們還介紹了從 Maven 倉(cāng)庫(kù)中的依賴解析機(jī)制。