第五節:Maven倉庫(下)

快照版本:
     定義:Snapshot版本代表不穩定、尚處於開發中的版本。
    我們知道,Maven的依賴管理是基於版本管理的,對於發佈狀態的artifact,如果版本號相同,即使我們遠程服務器上的組件比本地新,Maven也不會主動下載的。如果我們在開發階段都是基於正式發佈版本來做依賴管理,那麼遇到這個問題,就需要升級組件的版本號,可這樣就明顯不符合要求和實際情況了。
     定義一個組件/模塊爲快照版本,只需要在pom文件中在該模塊的版本號後加上-SNAPSHOT即可(注意這裏必須是大寫)
maven2會根據模塊的版本號(pom文件中的version)中是否帶有-SNAPSHOT來判斷是快照版本還是正式版本。如果是快照版本,那麼在mvn deploy時會自動發佈到快照版本庫中,會覆蓋老的快照版本,而在使用快照版本的模塊,在不更改版本號的情況下,直接編譯打包時,maven會自動從遠程服務器上下載最新的快照版本。如果是正式發佈版本,那麼在mvn deploy時會自動發佈到正式版本庫中,而使用正式版本的模塊,在不更改版本號的情況下,編譯打包時如果本地已經存在該版本的模塊則不會主動去遠程服務器上下載。
     試想一下這樣的情況,小張在開發模塊A的2.1版本,該版本還未正式發佈,與模塊A一同開發的還有模塊B,它由小張的同事季MM開發,B的功能依賴於A。在開發的過程中,小張需要經常將自己最新的構建輸出,交給季MM,供她開發和集成調試,Maven的快照版本機制就是爲了解決上述問題。在該例中,小張只需要將模塊A的版本設定爲2.1-SNAPSHOT,然後發佈到私服中,在發佈的過程中,Maven會自動爲構件打上時間戳。比如:2.1-20091214.221414-13就表示2009年12月14日 22點14分14秒的第13次快照。有了該時間戳,Maven就能隨時找到倉庫中該構件2.1-SNAPSHOT版本最新的文件。這時,季MM配置對於模塊A的2.1-SNAPSHOT版本的依賴,當她構件模塊B的時候Maven會自動從倉庫中檢查模塊A的2.1-SNAPSHOT的最新構件,當發現有更新時便進行下載。默認情況下,Maven每天檢查一次更新(由倉庫配置的updatePolicy控制),用戶也可以使用命令行-U參數強制讓Maven檢查更新,如:mvn clean install-U
     注意:快照版本應該只在組織內部的項目和模塊間依賴使用(開發階段),項目不應該依賴於任何組織外部的快照版本的構件,因爲由於快照版本的不穩定性,會使構建存在潛在的危險。

從倉庫解析依賴的機制:
     Maven是根據怎樣的規則從倉庫解析並使用依賴構件的呢?
     當本地倉庫沒有依賴構件的時候,Maven會自動從遠程倉庫下載。當依賴版本爲快照版本的時候,Maven會自動找到最新的的快照。這背後的依賴解析機制可以概括如下:
  1. 當依賴的範圍是system的時候,Maven直接從本地文件系統解析構件。
  2. 根據依賴座標計算倉庫路徑後,嘗試直接從本地倉庫尋找構件,如果發現相應構件,則解析成功。
  3. 在本地倉庫不存在相應構件的情況下,如果依賴的版本是顯式的發佈版本構件,如:1.2,2.1等,則遍歷所有的遠程倉庫,發現後,下載並解析使用。
  4. 如果依賴的版本是SNAPSHOT,則基於更新策略讀取所有遠程倉庫的元數據groupId/artifactId/version/mavenmetadata.xml,將其與本地倉庫的對應元數據合併後,得到最新快照版本的值,然後基於該值檢查本地倉庫,或者從遠程倉庫下載。
  5. 如果最後解析得到的構件版本是時間戳格式的快照,如:1.4-20091104.121450-121,則複製其時間戳格式的文件到非時間戳格式,如:SNAPSHOT,並使用該非時間戳格式的構件
      當依賴的版本不明晰的時候,如:RELEASE,LATEST和SNAPSHOT,Maven就需要基於我們在POM文件中配置的遠程倉庫的更新策略來檢查更新。首先是<releases><enabled>和<snapshots><enabled>,只有倉庫開啓了對於發佈版本的支持時,才能訪問該倉庫的發佈版本構件信息,對於快照版本也是同理;
     其次要注意的是<releases>和<snapshots>的子元素<updatePolicy>,該元素配置了檢查更新的頻率。最後,用戶還可以從命令行加入參數-U,強制檢查更新,使用參數後,Maven就會忽略<updatePolicy>的配置。
當Maven檢查完更新策略,並決定檢查依賴更新的時候,就需要檢查倉庫元數據maven-metadata.xml。如:

     在XML文件列出了倉庫中存在的該構件所有可用的版本,同時latest元素指向了這些版本中最新的那個版本。而release元素指向了這些版本中最新的發佈版本Maven通過合併多個遠程倉庫及本地倉庫的元數據,就能計算出基於所有倉庫的latest和release分別是什麼,然後再解析具體的構件。這是Maven2時期使用的,Maven3不再支持在插件配置中使用LATEST和RELEASE。
     當依賴的版本設爲快照版本的時候,Maven也需要檢查更新,這時,Maven會檢查倉庫元數據groupId/artifactId/version/maven-metadata.xml,如例:
     
     該xml文件的snapshot元素包含timestamp和buildNumber兩個子元素,分別代表了這一快照的時間戳和構建號,基於這兩個元素可以得到該倉庫中此快照的最新構件版本實際爲1.4.2-20091213.221414-13。通過合併所有遠程倉庫和本地倉庫的元數據,Maven就能知道所有倉庫中該構件的最新快照。 

     下面我們來回憶一下SNAPSHOT版本構件的部署與下載流程:
  1. 在版本號後加上大寫的-SNAPSHOT
  2. mvn deploy的時候會Maven自動爲構件打上時間戳,然後覆蓋遠程倉庫的舊版本。
  3. 當另一個項目需要引用此構件時,先基於更新策略讀取所有遠程倉庫的元數據groupId/artifactId/version/mavenmetadata.xml,將其與本地倉庫的對應元數據合併後,如果我們發現遠程倉庫中的版本比本地倉庫中的版本要新,則需要更新本地倉庫中的構件。
鏡像:
    定義:如果倉庫X可以提供倉庫Y儲存的所有內容,那麼我們就認爲X時Y的一個鏡像。
    好處:
  • 對於默認的中央倉庫來說,在不配置鏡像的情況下,maven默認會使用中央庫.
  • maven中央庫在國外,有時候訪問會很慢,尤其是下載較大的依賴的時候,有時候速度會很慢,甚至會出現無法下載的情況.
  • 爲了解決依賴下載速度的問題,需要配置maven國內鏡像
     配置:maven鏡像有兩種配置,一種是在settings.xml中進行配置,這會對所有的Maven項目產生影響;第二種是在項目的pom.xml中進行配置,這隻會對當前項目產生影響。我們需要配置的是mirrors下的的子元素mirror:
    • id:鏡像倉庫的唯一標識。
    • name:鏡像倉庫的名稱。
    • url:鏡像倉庫的地址。
    • mirrorof:表示是誰的鏡像
如果倉庫鏡像需要認證,也可以基於該id配置倉庫認證。
      關於鏡像的一個常見的用法是與私服相結合。我們可以利用私服配置一個外部公共倉庫的鏡像,即我們將所有對外部公共倉庫,遠程服務器的訪問都路由到這個私服上。這樣做將配置集中到了私服,簡化了對遠程服務器的配置。在這種情況下,所有的構件都從私服獲得,私服就是所有倉庫的鏡像。

     該例子中<mirrorOf>的值爲*,表示配置的是所有Maven倉庫的鏡像。爲了應對複雜情況,<mirrorOf>還有其他配置。
    • <mirrorOf> * </mirrorOf>:匹配所有的遠程倉庫。
    • <mirrorOf>external: *  </mirrorOf>:匹配所有不在本機上的遠程倉庫,即使用localhost的除外,使用file://協議的除外。
    • <mirrorOf>A,B  </mirrorOf>:匹配倉庫A和B,多個倉庫用逗號間隔。
    • <mirrorOf>*,!C  </mirrorOf>:匹配所有的遠程倉庫,倉庫C除外。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章