|-1-更新內(nèi)容[6.從倉庫解析依賴的機(jī)制(重要)]
1Maven倉庫作用
倉庫用來存儲所有項(xiàng)目使用到構(gòu)件,在maven項(xiàng)目需要依賴時(shí)就從該倉庫中獲取需要的依賴添加到classpath供其使用缰泡。
1.1需求背景
非maven項(xiàng)目如果要使用依賴刀荒,在其項(xiàng)目目錄下有一個(gè)lib文件夾,用來存放當(dāng)前項(xiàng)目依賴的構(gòu)件或者架包棘钞。這樣就存在一個(gè)問題缠借,如果一個(gè)電腦上有10個(gè)項(xiàng)目,每個(gè)項(xiàng)目依賴的架包都有重復(fù)的宜猜,那么就會存在把相同架包在每個(gè)項(xiàng)目的lib目錄下都拷貝一份的情況泼返,當(dāng)公司需要統(tǒng)一換掉一個(gè)架包時(shí)就需要把每個(gè)項(xiàng)目的該架包都刪掉在重新拷貝。由此可見問題有2個(gè)姨拥。1是每個(gè)項(xiàng)目都有l(wèi)ib文件夾造成磁盤空間浪費(fèi)绅喉。2最重要的是不能統(tǒng)一管理所有的依賴。
maven倉庫就是用來解決上述問題的叫乌,所有的maven項(xiàng)目下都沒有l(wèi)ib文件夾柴罐,也就是maven項(xiàng)目不再各自存儲其依賴文件,它們只需要聲明這些依賴的坐標(biāo)憨奸,在需要的時(shí)候(例如革屠,編譯項(xiàng)目的時(shí)候需要將依賴加入到classpath中),Maven會自動根據(jù)坐標(biāo)到倉庫中找構(gòu)件排宰,并使用它們似芝。
為了實(shí)現(xiàn)重用,項(xiàng)目構(gòu)建完畢后生成的構(gòu)件也可以安裝或部署到倉庫中额各,供其他門項(xiàng)目使用国觉。
2Maven倉庫布局
2.1布局規(guī)則
倉庫一個(gè)文件系統(tǒng),里面存放個(gè)下載的所有依賴文件虾啦,那么這些依賴在倉庫中是按照什么樣規(guī)則存儲布局*的呢麻诀?
任何構(gòu)件都有其唯一的坐標(biāo),根據(jù)這個(gè)坐標(biāo)可以定義在倉庫中的唯一存儲路徑
路徑規(guī)則:groupId/artifactId/version/artifactId-verson.packaging傲醉。
比如:log4j:log4j:1.2.15這一依賴蝇闭,在倉庫的對應(yīng)路徑為: log4j/log4j/1.2.15/log4j-1.2.15.jar。
2.2本地倉庫中依賴文件夾中其它文件解釋
log4j-1.2.15.pom:log4j-1.2.15.jar依賴的pom文件硬毕,該文件在log4j-1.2.15.jar文件解壓后也能得到呻引,只是名稱為pom.xml。
_remote.repositories:該文件所在的遠(yuǎn)程倉庫信息吐咳。
log4j-1.2.15.jar.sha1:log4j-1.2.15.jar文件的校驗(yàn)和文件逻悠,log4j-1.2.15.jar文件下載后為了驗(yàn)證下載內(nèi)容是否完整元践,需要使用log4j-1.2.15.jar.sha1中的校驗(yàn)和值來比對。如果下載內(nèi)容不完整(網(wǎng)絡(luò)原因等)maven會作出相應(yīng)通知童谒。(下面遠(yuǎn)程倉庫配置有講解)
log4j-1.2.15.pom.sha1:log4j-1.2.15.pom的校驗(yàn)和文件单旁。
3倉庫的分類
3.1介紹
倉庫分為兩種,遠(yuǎn)程倉庫和本地倉庫饥伊,maven根據(jù)坐標(biāo)尋找構(gòu)件時(shí)象浑,會先在本地倉庫查找,本地找不到會到遠(yuǎn)程倉庫查找琅豆,找到后會下載到本地倉庫愉豺,如果本地和遠(yuǎn)程倉庫都找不到就會報(bào)錯(cuò)。
本地倉庫在本地計(jì)算機(jī)上茫因。
遠(yuǎn)程倉庫和本地倉庫相對蚪拦。
中央倉庫是Maven很想自帶的遠(yuǎn)程倉庫,它包含了大部分開源構(gòu)件节腐,默認(rèn)配置下外盯,當(dāng)本地倉庫找不到構(gòu)件就去遠(yuǎn)程倉庫下載,其中的遠(yuǎn)程倉庫默認(rèn)就是中央倉庫翼雀。此時(shí)需要連接外網(wǎng)下載構(gòu)件饱苟,下載構(gòu)件的時(shí)間會受網(wǎng)絡(luò)的影響。
私服是一種特殊的遠(yuǎn)程倉庫狼渊,為了節(jié)省帶寬時(shí)間箱熬,應(yīng)該在局域網(wǎng)內(nèi)假設(shè)一個(gè)私有的倉庫服務(wù)器,用其代理所有外部的遠(yuǎn)程倉庫狈邑,內(nèi)部項(xiàng)目在本地找不到時(shí)就到私服上下載城须,因?yàn)槭枪緝?nèi)部網(wǎng)絡(luò)下載起來就好很快,如果私服上沒有米苹,私服就會通過代理去下載糕伐。內(nèi)部的項(xiàng)目還能部署到私服上供其他項(xiàng)目使用。
其它公開的遠(yuǎn)程倉庫蘸嘶,常見的有JBoss Maven庫和Java.net Maven庫等良瞧。
3.2本地倉庫
3.2.1本地倉庫位置
- 本地倉庫默認(rèn)位置在${user.home}/.m2/repository目錄下。我的用戶名為liang训唱,則本地倉庫地址為C:\Users\liang.m2\repository\褥蚯,而Linux上的本地倉庫地址為home/liang/.m2/repository/注意Liunx中以點(diǎn)(.)開頭的文件或目錄默認(rèn)隱藏的,可以使用ls-a命令查看况增。
3.2.2修改本地倉庫位置
- 如果不喜歡默認(rèn)位置可以修改赞庶,修改本地倉庫位置
3.2.2三種方式添加構(gòu)件到本地倉庫
3.2.2.1從遠(yuǎn)程倉庫下載下來。
通過在項(xiàng)目的pom中配置依賴,dependency下載需要的依賴到本地倉庫歧强。
3.2.2.2 通過maven命令安裝maven項(xiàng)目到本體倉庫
- 在某個(gè)maven項(xiàng)目根目錄下執(zhí)行:mvn clean install命令就可以把項(xiàng)目以構(gòu)件形式安裝到本地倉庫中澜薄。(部署到私服上執(zhí)行mvn clean deploy后面講)
3.2.2.3安裝第三方構(gòu)件到本地倉庫
- 第三方,只是一個(gè)jar包誊锭,出現(xiàn)這種情況:別人開發(fā)好的一個(gè)jar包立镶,但是沒有發(fā)布到maven中央倉庫中俭厚,我需要在maven項(xiàng)目中使用,所以歉秫,我們可以通過命令將該jar包添加到本地倉庫中籽暇,這樣就可以在項(xiàng)目中聲明使用了温治,聲明一個(gè)構(gòu)件當(dāng)然需要groupId\artifactId、version戒悠。
- 需求:把jar:g:\edu.mit.jwi_2.3.3_jdk.jar 安裝到本地倉庫熬荆,并且自定義它的gourpId=local.edu.stanford; artifactId=edu.mit.jwi_jdk;version=2.3.3绸狐;packaging =jar
- 操作:在命令行中執(zhí)行如下命令即可卤恳。詳見:install:install-file
mvn install:install-file -Dfile=g:\edu.mit.jwi_2.3.3_jdk.jar -DgroupId=local.edu.stanford -DartifactId=edu.mit.jwi_jdk -Dversion=2.3.3 -Dpackaging=jar -DpomFile=g:\pom.xml
關(guān)于部署第三方構(gòu)件到Nexus私服倉庫,請查看maven---9使用Nexus創(chuàng)建私服----->5.3手動部署第三方構(gòu)件至Nexus
3.3遠(yuǎn)程倉庫
- 遠(yuǎn)程倉庫相對本地倉庫,本地倉庫不存在的構(gòu)件才會從遠(yuǎn)程倉庫下載寒矿,并保存在本地倉庫中突琳。對maven來說,每個(gè)用戶只有一個(gè)本地倉庫符相,但可以配置訪問很多遠(yuǎn)程倉庫拆融。
3.4中央倉庫
- 由于最原始的本地倉庫是空的,Maven必須知道至少一個(gè)可用的遠(yuǎn)程倉庫啊终,才能在執(zhí)行maven命令的時(shí)候下載需要的構(gòu)件镜豹。中央倉庫就是這樣一個(gè)默認(rèn)的遠(yuǎn)程倉庫,中央倉庫的信息在超級Pom中配置蓝牲,所有的maven項(xiàng)目都會繼承超級POM趟脂。 超級POM的位置: $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>
- 解釋 使用id=central對倉庫進(jìn)行唯一標(biāo)識昔期;name倉庫名稱;url倉庫地址肄渗;layout=default指定倉庫的布局镇眷,default也就是上面提到布局規(guī)則;enabled=false表示不從該中央倉庫下載快照版本的構(gòu)件翎嫡。
3.5私服
- 私服是一種特殊的遠(yuǎn)程倉庫欠动,它是架設(shè)在局域網(wǎng)的倉庫服務(wù),私服代理廣域網(wǎng)上的遠(yuǎn)程倉庫,供局域網(wǎng)使用具伍。
3.5.1架設(shè)私服的好處
節(jié)省資金的外網(wǎng)帶寬翅雏,利用私服代理外部倉庫之后,對外的重復(fù)構(gòu)件下載便得以下手人芽,降低外網(wǎng)帶寬壓力望几。
加速M(fèi)aven構(gòu)建。不停地連接請求外部倉庫是什么耗時(shí)的萤厅,但是maven的一些內(nèi)部機(jī)制(如快照更新檢查)要求Maven在執(zhí)行構(gòu)建的時(shí)候不停地檢查遠(yuǎn)程倉庫數(shù)據(jù)橄抹。因此,當(dāng)項(xiàng)目配置了很多外部遠(yuǎn)程倉庫的時(shí)候惕味,構(gòu)建速度會降低楼誓。使用私服解決這問題,因?yàn)镸aven只需要檢查局域網(wǎng)內(nèi)私服的數(shù)據(jù)時(shí)名挥,構(gòu)建速度便提高疟羹。
部署第三方構(gòu)件,當(dāng)某個(gè)構(gòu)件無法從任何一個(gè)遠(yuǎn)程倉庫獲取怎么辦禀倔?比如Oracle的JDBC驅(qū)動由于版權(quán)原因不能發(fā)布到公共倉庫中榄融。建立私服后,便可以將這些構(gòu)件部署到這個(gè)內(nèi)部倉庫中救湖,供內(nèi)部Maven項(xiàng)目使用愧杯。
提高穩(wěn)定性,增強(qiáng)控制捎谨。對于遠(yuǎn)程倉庫當(dāng)外網(wǎng)不可用時(shí)民效,maven構(gòu)建有可能因?yàn)橐蕾嚊]有下載而不可行,私服后涛救,即使沒有網(wǎng)畏邢,如果該構(gòu)件只有之前被其它人下載過就會存在私服上,此時(shí)我下時(shí)就可以不用連接外網(wǎng)直接就可以從私服上下載到检吆。同時(shí)私服軟件(nexus)還提供了額外的管理功能舒萎。
降低中央倉庫的負(fù)荷。
4遠(yuǎn)程倉庫配置(包含更新策略)
4.1配置
默認(rèn)的中央倉庫無法滿足項(xiàng)目需求蹭沛,可能需要的構(gòu)件在另外一個(gè)遠(yuǎn)程倉庫臂寝,如JBoss Maven倉庫,可以POM中配置該倉庫摊灭。
<repositories>
....
<repository>
<id>jboss</id>
<name>JBoss Repository</name>
<url>https://repository.jboss.com/maven2/</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>
....
</repositories>
4.1.1解釋
- id要唯一咆贬,如果出現(xiàn)重復(fù)會覆蓋掉之前的。
- 對于releases的enabled=true表示開啟JBoss倉庫的發(fā)布版本下載支持帚呼。根據(jù)以上配置掏缎,maven只從JBoss倉庫下載發(fā)布版本的構(gòu)件不會下載快照版本皱蹦。
- 對于releases和snapshots來說,除了enabled還包含兩個(gè)子元素updataPolicy和checksumPolicy
<releases>
<enabled>true</enabled>
<updataPolicy>daily</updataPolicy>
<checksumPolicy>warn</checksumPolicy>
</releases>
- updataPolicy:配置maven從遠(yuǎn)程倉庫檢查更新的頻率眷蜈,對同一個(gè)版本(如:log4j.1.2.15.jar)的構(gòu)件如果發(fā)現(xiàn)有更新(如:對log4j.1.2.15.jar進(jìn)行了內(nèi)容修復(fù)但是版本都不變)會下載最新的沪哺。默認(rèn)daily-maven每天檢查一次
never-從不檢查;always-每次構(gòu)件都要檢查更新酌儒;interval:X -每隔X分鐘檢查一次更新(X為整數(shù))
當(dāng)然:用戶可以使用參數(shù)-U,強(qiáng)制檢查更新辜妓,使用參數(shù)后,maven就會忽略updatePolicy的配置忌怎。
至于如何更新請看下面的(6從倉庫解析依賴的機(jī)制)籍滴,其中涉及到從遠(yuǎn)程下載maven-metadata.xml文件。 - checksumPolicy:用來配置Maven檢查校驗(yàn)和文件失敗后的策略榴啸。構(gòu)件被部署到maven倉庫中時(shí)會同時(shí)部署對應(yīng)的校驗(yàn)和文件异逐,maven會驗(yàn)證校驗(yàn)和文件以確定下載的構(gòu)件是否完整,如果校驗(yàn)失敗插掂,怎么辦?策略有3中:(默認(rèn)值)warn-maven會執(zhí)行構(gòu)建時(shí)輸出警告信息腥例;fail-maven遇到校驗(yàn)和錯(cuò)處就讓構(gòu)建失敻ㄉ;ignore-使maven完全忽略校驗(yàn)和錯(cuò)誤燎竖。
4.2遠(yuǎn)程倉庫的認(rèn)證
- 有時(shí)候處于安全考慮璃弄,需要提供認(rèn)證信息才能訪問一些遠(yuǎn)程倉庫。為了能讓maven訪問倉庫內(nèi)容构回,就需要配置認(rèn)證信息夏块,認(rèn)證信息的配置不會在pom.xml配置,而是在settings.xml中配置纤掸,因?yàn)閜om會被提交到代碼倉庫中供所有成員訪問脐供,而settings.xml一般只放在本機(jī)。
- 假設(shè)我在pom.xml中配置id=my-proj的遠(yuǎn)程倉庫借跪,需要認(rèn)證信息政己,則在settings.xml中配置如下:
<settings>
...
<servers>
<server>
<id>my-proj</id>
<username>repo-user</username>
<password>repo-pwd</password>
</server>
</servers>
...
</settings>
這里的id=my-proj一定要和pom.xml中倉庫的id一致,這是它們之間唯一的聯(lián)系掏愁。
settings.xml的servers中就是用來配服務(wù)器授權(quán)信息的歇由,當(dāng)然不僅可以配置倉庫服務(wù)器認(rèn)證信息,還可以配置其它的比如tomcat服務(wù)器授權(quán)信息也可以在這里配置果港。
4.3部署當(dāng)前maven項(xiàng)目至遠(yuǎn)程倉庫
4.3.1需求
- 私服的一個(gè)作用是部署公司內(nèi)部生成的構(gòu)件以及一些無法從外部倉庫獲取的構(gòu)件沦泌。那么如何把maven項(xiàng)目部署到私服上或者其他的遠(yuǎn)程服務(wù)器上呢?
4.3.2操作步驟
步驟-1配置pom.xml
需要編寫pom.xml文件辛掠,配置distributionManagement元素谢谦。
<distributionManagement>
<repository>
<id>proj-releases</id>
<name>Proj Release Repository</name>
<url>http://192.168.1.100/content/repositories/proj-releases</url>
</repository>
<snapshotRepository>
<id>proj-snapshots</id>
<name>Proj Snapshot Repository</name>
<url>http://192.168.1.100/content/repositories/proj-snapshots</url>
</snapshotRepository>
</distributionManagement>
- distributionManagement包含repository和snapshotRepository子元素,前者表示發(fā)布版本構(gòu)件的倉庫,后者表示快照版本的倉庫他宛。
- id為遠(yuǎn)程倉庫的唯一標(biāo)識船侧,name是為了方便人閱讀,url表示該倉庫的地址厅各。
步驟-2配置settings.xml
- 往倉庫部署構(gòu)件往往需要認(rèn)證镜撩,配置方式如上面所講,只需要配置settings.xml中的server元素队塘。同時(shí)其id要與倉庫id匹配袁梗。不論部署還是下載構(gòu)件,當(dāng)需要認(rèn)證時(shí)配置方式一樣憔古。
步驟-3使用部署命令
- 在命令行運(yùn)行 mvn clean deploy遮怜。Maven就會將項(xiàng)目構(gòu)建輸出的構(gòu)件部署到配置對應(yīng)的遠(yuǎn)程倉庫,如果項(xiàng)目版本是快照版本就部署到快照版本倉庫地址鸿市,同理發(fā)布版本倉庫地址锯梁。
5快照版本
任何一個(gè)項(xiàng)目或者構(gòu)件都必須由自己的版本,1.0.0焰情、1.2-alpha-4陌凳、2.0、2.1-SNAPSHOT内舟,其中2.1-SNAPSHOT是不穩(wěn)定的快照版本合敦。
5.1需求
小張和李MM負(fù)責(zé)公司同一個(gè)項(xiàng)目的不同模塊,小張負(fù)責(zé)A模塊验游,李MM負(fù)責(zé)B模塊充岛,但是B模塊的開發(fā)過程中依賴A模塊,為了保證快速開發(fā)耕蝉,小張的模塊A內(nèi)容的變化應(yīng)該盡快的讓李MM獲取到崔梗,但是李MM獲取小張模塊A是通過groupId、artifactId赔硫、version來配置獲取的炒俱,怎樣才能獲取最新的呢?兩人不停的改變版本號爪膊? 那么小張和李MM怎么配合開發(fā)呢权悟?
5.2方案
方案1:讓李MM自己簽出模塊A的源代碼進(jìn)行構(gòu)建,這種方法能夠確保李MM得到模塊A的最新構(gòu)件推盛,不過她不得去自己構(gòu)建A峦阁,當(dāng)構(gòu)建失敗時(shí),她會一頭霧水不得不去找小張解決耘成,效率低榔昔。
方案2:小張重復(fù)部署模塊A的2.1版供李MM下載驹闰。問題:雖然小張能夠保證倉庫中的構(gòu)件是最新的,但是對于maven來說撒会,同樣的版本就是同樣的構(gòu)件嘹朗,所以李MM本地倉庫包含了A2.1,maven就不會再對倉庫進(jìn)行更新了诵肛,除非執(zhí)行maven命令之前屹培,清除本地倉庫,效率低怔檩。
方案3:不停更新版本2.1.1褪秀、2.1.2、2.1.3 ....薛训。小張和小麗都需要不停的更新Pom,如果更多模塊依賴A媒吗,就會涉及更多pom更改。這就涉及到兩問題:小張更新版本號時(shí)要對李MM說一下讓她也更新一下乙埃。其次是版本號濫用闸英。
-
方案4(快照):解決上述問題,使用快照機(jī)制介袜,該例中自阱,小張只需要將模塊A的版本設(shè)定為2.1-SNAPSHOT,然后發(fā)布到私服中米酬,在發(fā)布過程中maven會自動為構(gòu)件打上時(shí)間戳,比如2.1-20161119-105936-12:表示2016年11月19號10點(diǎn)59分36秒第12次修改趋箩,有了該時(shí)間戳赃额,Maven就能隨時(shí)找到該倉庫中該構(gòu)件2.1-SNAPSHOT的最新構(gòu)件。也就是2.1-SNAPSHOT對應(yīng)了許多帶有不同時(shí)間戳的構(gòu)件叫确。李MM這邊配置對于模塊A的2.1-SNAPSHOT版本跳芳,當(dāng)構(gòu)建模塊B時(shí)發(fā)現(xiàn)有更新便進(jìn)行下載,默認(rèn)情況下竹勉,maven每天檢查一次更新(由倉庫配置的updataPolicy控制飞盆,上面有講),李MM也可以使用命令行-U參數(shù)強(qiáng)制maven更新次乓,如:mvn clean install-U 吓歇。
- 基于快照機(jī)制,這樣小張和李MM就不用不斷的修改版本了票腰。小張構(gòu)建成功后發(fā)布到倉庫城看,李MM不用手工操作,她就可以得到A的最新快照版本構(gòu)件杏慰。
5.3使用經(jīng)驗(yàn)
當(dāng)項(xiàng)目測試后需要發(fā)布時(shí)测柠,將快照版改為發(fā)布版本炼鞠。如2.1-SNAPSHOT改為2.1,且只對應(yīng)唯一構(gòu)件轰胁,而2.1-SNAPSHOT對應(yīng)了許多帶有不同時(shí)間戳的構(gòu)件谒主。
快照版使用場景 快照版只應(yīng)該在公司內(nèi)部項(xiàng)目使用,因?yàn)轫?xiàng)目成員對不同的模塊有清晰的理解和控制赃阀。項(xiàng)目不應(yīng)該依賴第三方的快照版構(gòu)件霎肯。那樣存在不受控制和不穩(wěn)定性。
6從倉庫解析依賴的機(jī)制(重要)
上一節(jié)介紹了Maven依賴機(jī)制凹耙,本章闡述了Maven倉庫姿现,這兩者是如何具體聯(lián)系到一起的呢?Maven是根據(jù)怎樣的規(guī)則從倉庫解析并使用依賴構(gòu)件的呢肖抱?
6.1解析構(gòu)件步驟
該步驟適用于插件备典、依賴的解析
- 當(dāng)依賴范圍是system時(shí)候,Maven直接從本地文件解析構(gòu)件意述。
- 根據(jù)依賴坐標(biāo)計(jì)算倉庫路徑后提佣,先從本地倉庫尋找構(gòu)件,如果發(fā)現(xiàn)則解析成功荤崇。
- 本地倉庫沒找到拌屏,如果依賴版本(version)是發(fā)布版構(gòu)件,即1.2,2.3等术荤,則遍歷遠(yuǎn)程倉庫倚喂,發(fā)現(xiàn)后下載并解析使用。
- 如果version是SNAPSHOT版瓣戚,如:2.1-SNAPSHOT端圈,則基于更新策略(updatepolicy)讀取所有遠(yuǎn)程倉庫的元數(shù)據(jù)groupId/artifactId/version/maven-metadata.xml,將其與本地倉庫的對應(yīng)元數(shù)據(jù)合并后子库,得到最新快照版本的值舱权,然后基于該值檢查本地倉庫,或者從遠(yuǎn)程倉庫下載仑嗅。(如果最新版還是之前的值就不需要去遠(yuǎn)程倉庫下載了)宴倍。
注意:這一步因?yàn)閡pdatepolicy的原因,可能要求本機(jī)能連接到遠(yuǎn)程倉庫(遠(yuǎn)程倉庫可以是私服或者中央倉庫仓技,一般只有自己的項(xiàng)目會使用SNAPSHOT鸵贬,所以大多數(shù)是私服) - 如果最后解析得到構(gòu)件版本是時(shí)間戳格式的快照,如1.4.1-20161121.121432-121則復(fù)制其時(shí)間戳格式的文件至非時(shí)間戳格式脖捻,如SNAPSHOT恭理,并使用該時(shí)間戳格式的構(gòu)件。
- 當(dāng)依賴的version值為RELEASE時(shí)(不建議)郭变,Maven會基于updatepolicy策略讀取遠(yuǎn)程倉庫的元數(shù)據(jù)groupId/artifactId/maven-metadata.xml颜价,將其與本地倉庫相對應(yīng)元數(shù)據(jù)合并后涯保,計(jì)算出最新版本的RELEASE值(穩(wěn)定版),然后基于這個(gè)值檢查本地和遠(yuǎn)程倉庫周伦,步驟如2和3夕春。
注意:存在潛在問題,如某個(gè)依賴的1.1版本與1.2版本可能發(fā)生一些接口變化专挪,從而導(dǎo)致當(dāng)前Maven項(xiàng)目構(gòu)建失敗及志,所以依賴的版本最好確定
注:第4步驟在6.2、6.3節(jié)有詳解
6.2解析進(jìn)一步說明
當(dāng)構(gòu)件版本version為RELEASE寨腔,或?yàn)榭煺瞻嫠俪蓿琺aven都需要基于倉庫配置的更新策略updatePolicy來檢查更新最新版本,那么更新策略就是上面4.1迫卢、4.1.1所講的倚搬。(其中的倉庫可以是存放依賴的倉庫也可以是存放插件的倉庫),當(dāng)構(gòu)件的version有穩(wěn)定版值(如2.1),而且在本地倉庫有該構(gòu)件后乾蛤,如果執(zhí)行的maven命令沒有加-U參數(shù)每界,那么根據(jù)6.1的解析步驟,在第2步就返回該構(gòu)件家卖,而不會參照updatePolicy去檢查更新眨层。
1.首先通過配置某個(gè)遠(yuǎn)程倉庫中<releases>、<snapshots>的<enabled>來確定是否支持從該倉庫下載發(fā)布版本和快照版本構(gòu)件的支持上荡,如果不支持趴樱,則不會下載相應(yīng)類型的構(gòu)件(發(fā)布版和快照版)。
2.如果第1步通過酪捡,在通過配置<releases>伊佃、<snapshots>的<updatePolicy>來配置檢查更新依賴的頻率:每日更新、永遠(yuǎn)更新沛善、從不更新、自定義時(shí)間間隔更新塞祈。如果updatePolicy為“從不更新”則不會檢查遠(yuǎn)程倉庫該插件的內(nèi)容是否變化金刁,而是直接使用本地構(gòu)件。 當(dāng)然可以通過在命令中加入?yún)?shù)-U议薪,強(qiáng)制檢查更新尤蛮。(使用-U會強(qiáng)制檢查更新pom.xml中所有依賴和插件不管version有沒有值)。
6.3 快照版和穩(wěn)定版解析構(gòu)件詳解
6.3.1解析時(shí)機(jī)
- 首先maven項(xiàng)目的pom.xml文件中包含該類構(gòu)件斯议,當(dāng)在項(xiàng)目上執(zhí)行的mvn命令會用到該類構(gòu)件時(shí)就會觸發(fā)解析事件产捞。
6.3.2解析說明
- 當(dāng)version值為RELEASE或?yàn)榭煺瞻鏁r(shí),通過2步來解析得到構(gòu)件:1.maven需要通過策略來計(jì)算得到構(gòu)件版本的值哼御。2.找到值之后就按照常規(guī)的解析步驟解析構(gòu)件:先在本地倉庫找坯临,找不到再到遠(yuǎn)程倉庫找焊唬。下面就來介紹第1步。
6.3.3步驟1:獲取構(gòu)件版本值
- 先判斷遠(yuǎn)程倉庫是否支持相應(yīng)構(gòu)件(快照版看靠、發(fā)布版)下載赶促,不支持則解析失敗,支持則再判斷updatePolicy指定的更新頻率是否到達(dá)挟炬,如果更新頻率沒到鸥滨,則使用上一次更新得到的結(jié)果,該結(jié)果可能是上次成功的結(jié)果也可能是上次解析失敗的結(jié)果谤祖。如果前一次解析失斝鲎摇(網(wǎng)絡(luò)等原因),則這一次解析返回結(jié)果就是上一次失敗原因粥喜。如果前一次解析成功凸主,則這一次直接返回上一次解析得到的值。
- 當(dāng)更新頻率達(dá)到后則執(zhí)行步驟2得到具體的構(gòu)件版本值容客,如下秕铛。
6.3.4步驟2:獲取構(gòu)件版本值
當(dāng)構(gòu)件version=RELEASE情況(不建議這么設(shè)值)
maven會讀取所有遠(yuǎn)程倉庫的元數(shù)據(jù)groupId/artifactId/maven-metadata.xml,將其與本地倉庫的對應(yīng)元數(shù)據(jù)(本地倉庫元數(shù)據(jù)為為本地最后一次更新該構(gòu)件從遠(yuǎn)程倉庫下載下來的文件)合并后缩挑,得到最新快照版本的值但两。
以nekohtml構(gòu)件為例,該構(gòu)件的依賴配置如下:該構(gòu)件來自于中央倉庫供置,該依賴倉庫不支持快照版本谨湘,只支持發(fā)布本而且更新策略為“每天更新一次”。因?yàn)槲冶镜嘏渲昧薸d為nexus-mirror的鏡像從私服中下載構(gòu)件芥丧。則nekohtml構(gòu)件在本地倉庫中的元數(shù)據(jù)文件名為maven-metadata-nexus-mirror.xml紧阔,文件內(nèi)容如下:
<?xml version="1.0" encoding="UTF-8"?>
<metadata modelVersion="1.1.0">
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
<version>1.9.22</version>
<versioning>
<latest>1.9.22</latest>
<release>1.9.22</release>
<versions>
<version>1.9.7</version>
<version>1.9.8</version>
。续担。擅耽。。物遇。省略其它版本
<version>1.9.21</version>
<version>1.9.22</version>
</versions>
<lastUpdated>20150417210244</lastUpdated>
</versioning>
</metadata>
- 該xml文件列出來倉庫中存在該構(gòu)件的所有版本乖仇,同時(shí)latest元素指向了這些版本中最新的那個(gè)版本(快照版或發(fā)布版),為1.9.22询兴,release元素指向了這些版本中最新發(fā)布版本乃沙。由于不支持快照版,所以該文件中沒有快照版本诗舰。lastUpdated是構(gòu)件最新更新的時(shí)間警儒,該時(shí)間是構(gòu)件創(chuàng)建者發(fā)布該構(gòu)件到中央倉庫的時(shí)間。
- maven在更新時(shí)會從所有遠(yuǎn)程倉庫中下載該構(gòu)件的元數(shù)據(jù)到本地眶根,然后和本地的進(jìn)行合并蜀铲,就可以得到所有倉庫中該構(gòu)件的最新版本值边琉。獲取構(gòu)件版本值成功。
當(dāng)構(gòu)件version為快照版情況
maven讀取所有遠(yuǎn)程倉庫的元數(shù)據(jù)groupId/artifactId/version/maven-metadata.xml蝙茶,將其與本地倉庫的對應(yīng)元數(shù)據(jù)合并后艺骂,得到最新快照版本的值,該元數(shù)據(jù)在version目錄下面隆夯,而version沒有值時(shí)檢查的元數(shù)據(jù)在artifactId目錄下面钳恕。
那么maven如何根據(jù)maven-metadata.xml來檢查更新快照版的最新構(gòu)件的版本值的呢?首先明白一個(gè)快照版本0.0.1-SNAPSHOT對應(yīng)多個(gè)構(gòu)件蹄衷,maven就是找出那個(gè)最新的構(gòu)件忧额。
下面以iqasweb項(xiàng)目為例,該項(xiàng)目version0.0.1-SNAPSHOT愧口。項(xiàng)目在本地倉庫元數(shù)據(jù)文件為maven-metadata-nexus-snapshots.xml睦番,內(nèi)容如下:
<?xml version="1.0" encoding="UTF-8"?>
<metadata modelVersion="1.1.0">
<groupId>com.cnu.iqas</groupId>
<artifactId>iqasweb</artifactId>
<version>0.0.1-SNAPSHOT</version>
<versioning>
<snapshot>
<timestamp>20170111.062153</timestamp>
<buildNumber>4</buildNumber>
</snapshot>
<lastUpdated>20170111062153</lastUpdated>
<snapshotVersions>
<snapshotVersion>
<extension>war</extension>
<value>0.0.1-20170111.062153-4</value>
<updated>20170111062153</updated>
</snapshotVersion>
<snapshotVersion>
<extension>pom</extension>
<value>0.0.1-20170111.062153-4</value>
<updated>20170111062153</updated>
</snapshotVersion>
<snapshotVersion>
<classifier>sources</classifier>
<extension>jar</extension>
<value>0.0.1-20170111.062153-4</value>
<updated>20170111062153</updated>
</snapshotVersion>
</snapshotVersions>
</versioning>
</metadata>
- 該xml文件的snapshot元素包含的timestamp和buildNumber兩個(gè)元素代表了快照的時(shí)間戳和構(gòu)建號,即version版本下的第幾次構(gòu)建的耍属,基于這兩個(gè)元素可以得到該倉庫中此快照的最新構(gòu)件版本實(shí)際為0.0.1-20170111.062153-4托嚣。lastUpdated是構(gòu)件最新更新的時(shí)間。snapshotVersions標(biāo)簽中內(nèi)容是構(gòu)件產(chǎn)生的其它文件的版本標(biāo)識厚骗。
在nexus私服中可以看到該版本的構(gòu)件有4個(gè)示启,正好對應(yīng)4次構(gòu)建。
- maven讀取所有遠(yuǎn)程倉庫的元數(shù)據(jù)groupId/artifactId/**version/maven-metadata.xml领舰,將其與本地倉庫的對應(yīng)元數(shù)據(jù)合并后夫嗓,得到最新快照版本的值。獲取版本值成功冲秽。
6.4常見解析失敗
在根據(jù)6.1的執(zhí)行步驟解析構(gòu)件時(shí)難免因?yàn)橐恍┏霈F(xiàn)一些錯(cuò)誤舍咖,常見一個(gè)錯(cuò)誤如下:
-
解析失敗原因
如果執(zhí)行到第3步驟,因?yàn)橐恍┰颍ū热鐩]網(wǎng)絡(luò))從遠(yuǎn)程倉庫下載構(gòu)件失旓鄙!(不管是私服還是中央倉庫)排霉,則依賴解析失敗。 - 解析失敗情況演示
<dependency>
<groupId>com.github.docker-java</groupId>
<artifactId>docker-java</artifactId>
<version>3.0.4</version>
</dependency>
第一次解析上面依賴因?yàn)闆]網(wǎng)絡(luò)執(zhí)行到第3步失斆裰帷:
失敗后在本地倉庫產(chǎn)生的文件如下:
docker-java-3.0.4.jar.lastUpdated文件的內(nèi)容如下:
#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
#Mon Jan 09 21:21:29 CST 2017
http\://172.19.201.155\:8081/repository/maven-public/.lastUpdated=1483968089340
http\://172.19.201.155\:8081/repository/maven-public/.error=
-
解決
讓本機(jī)可以連接到遠(yuǎn)程倉庫攻柠,在執(zhí)行編譯,結(jié)果還是錯(cuò)誤杉武,因?yàn)閙aven緩存了上傳執(zhí)行失:
執(zhí)行命令加上-U參數(shù),或者將解析失敗構(gòu)件在本地倉庫中的xxxx.lastupdated文件刪掉辙售,就不會返回緩存了轻抱。
7鏡像
- 如果倉庫X可以提供倉庫Y存儲的所有內(nèi)容,那么就可以認(rèn)為X是Y的一個(gè)鏡像旦部。舉個(gè)栗子:http://maven.net.cn/content/groups/public/ 是中央倉庫http://repol.maven.org/maven2/ 在中國的鏡像祈搜,由于地理位置原因较店,該鏡像提供的下載服務(wù)更快。因此可以配置maven使用該鏡像來替代中央倉庫容燕,編輯settings.xml梁呈。
<settings>
<mirrors>
<!-- mirror
| Specifies a repository mirror site to use instead of a given repository. The repository that
| this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
| for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
| -->
<mirror>
<id>maven.net.cn</id>
<name>one of the central mirrors in China</name>
<url>http://maven.net.cn/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
</settings>
- 該例中mirrorOf為central,表示該配置為中央倉庫的鏡像蘸秘,任何對于中央倉庫的請求都會轉(zhuǎn)至該鏡像官卡,用戶也可以使用該方法配置其它倉庫的鏡像。另外三個(gè)參數(shù)和配置一般遠(yuǎn)程倉庫一樣醋虏。
- 鏡像一般用在私服上寻咒,因?yàn)樗椒砹巳魏瓮獠康墓矀}庫,因此對于組織內(nèi)部的maven用戶來說颈嚼,使用一個(gè)私服地址就等于使用所有外部倉庫毛秘。
- 為滿足復(fù)雜需求,maven支持更高級的鏡像配置阻课。
- <mirrorOf>*</mirrorOf> :匹配所有遠(yuǎn)程倉庫叫挟。
- <mirrorOf>external:*</mirrorOf> :匹配所有遠(yuǎn)程倉庫,使用localhost的除外限煞,使用file://協(xié)議的除外抹恳。
- <mirrorOf>repo1,repo2</mirrorOf> :匹配倉庫repo1,repo2,多個(gè)使用逗號分隔晰骑。
- <mirrorOf>*,!repo1</mirrorOf> :匹配所有遠(yuǎn)程倉庫适秩,repo1除外。
8倉庫搜索服務(wù)
我們?nèi)绾螌ふ倚枰囊蕾囁队撸韵率菐讉€(gè)公共Maven倉庫搜索服務(wù)秽荞,都代理了主流的Maven公共倉庫,如中央倉庫抚官、JBoss扬跋、java.net等,搜索關(guān)鍵字有:類名凌节、坐標(biāo)钦听、校驗(yàn)和搜索等
8.1Sonatype Nexus
8.2Jarvana
8.3MVNborwser
8.4MVNrepository
有什么不懂的一起探討一下吧,我也是在學(xué)習(xí)的路上倍奢。喜歡給我點(diǎn)個(gè)贊吧(哈哈)朴上,我會繼續(xù)努力的。
注意
- 鏡像配置的地址卒煞,一般應(yīng)該是一個(gè)包含了多個(gè)倉庫的倉庫組地址痪宰,這個(gè)倉庫組里面應(yīng)該包含中央倉庫、自己的release倉庫,自己的snapshot倉庫衣撬,第三方release倉庫等乖订。公司的倉庫是個(gè)坑。具练。乍构。,不要配置鏡像扛点。