Maven詳解之倉庫------本地倉庫、遠端倉庫
在Maven中,任何一個依賴、外掛或者專案構建的輸出,都可以稱之為構件。
Maven在某個統一的位置儲存所有專案的共享的構件,這個統一的位置,我們就稱之為倉庫。(倉庫就是存放依賴和外掛的地方)
任何的構件都有唯一的座標,Maven根據這個座標定義了構件在倉庫中的唯一儲存路徑,
解讀Maven在倉庫中的儲存路徑:
1.基於groupId準備路徑,將句點分隔符轉成路徑分隔符,就是將 "." 轉換成 "/" ; example: org.testng --->org/testng
2.基於artifactId準備路徑,將artifactId連線到後面:org/testng/testng
3.使用version準備路徑,將version連線到後面:org/testng/testng/5.8
4.將artifactId於version以分隔符連字號連線到後面:org/testng/testng/5.8/tesng-5.8
5.判斷如果構件有classifier,就要在 第4項 後增加 分隔符連字號 再加上 classifier,org/testng/testng/5.8/tesng-5.8-jdk5
6.檢查構件的extension,如果extension存在,則加上句點分隔符和extension,而extension是由packing決定的,org/testng/testng/5.8/tesng-5.8-jdk5.jar
到這裡我們就明白了Maven 對於構件儲存的細節。
Maven 倉庫的分類:
maven的倉庫只有兩大類:
1.本地倉庫
2.遠端倉庫,在遠端倉庫中又分成了3種:
2.1 中央倉庫
2.2 私服
2.3 其它公共庫
1.本地倉庫
顧名思義,就是Maven在本地儲存構件的地方。
注:maven的本地倉庫,在安裝maven後並不會建立,它是在第一次執行maven命令的時候才被建立
maven本地倉庫的預設位置:無論是Windows還是Linux,在使用者的目錄下都有一個.m2/repository/的倉庫目錄,這就是Maven倉庫的預設位置
如何更改maven預設的本地倉庫的位置:這裡要引入一個新的元素:localRepository,它是存在於maven的settings.xml檔案中
1.1 更改配置使用者範圍的本地倉庫:
先在/.m2/目錄下建立settings.xml檔案,然後在~/.m2/settings.xml,設定localRepository元素的值為想要的倉庫地址
<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 | The path to the local repository maven will use to store artifacts. | | Default: ${user.home}/.m2/repository--> <localRepository>D:/myworkspace/maven_repository</localRepository> <!-- interactiveMode | This will determine whether maven prompts you when it needs input. If set to false, | maven will use a sensible default value, perhaps based on some other setting, for | the parameter in question. | | Default: true <interactiveMode>true</interactiveMode> --> ... ...
這時候,maven的本地倉庫地址就變成了 D:\maven_new_repository ,注:此時配置的maven的本地倉庫是屬於使用者範圍的。
1.2 更改配置全域性範圍的本地倉庫:
在M2_HOME/conf/settings.xml(D:\soft\maven\apache-maven-3.3.3\confsettings.xml\settings.xml)中更改配置,更改配置的方法同上
注:此時更改後,所有的使用者都會受到影響,而且如果maven進行升級,那麼所有的配置都會被清除,所以要提前複製和備份M2_HOME/conf/settings.xml檔案
故:一般情況下不推薦配置全域性的settings.xml
1.3 工程使用倉庫配置的優先順序順序
這個確實是有個優先順序的,應該是pom>使用者級別>全域性級別 例:如果pom中不配置,就取使用者級別,如果使用者級別也沒有配置,就取全域性級別
2. 遠端倉庫
2.1 說到遠端倉庫先從 最核心的中央倉庫開始,中央倉庫是預設的遠端倉庫,maven在安裝的時候,自帶的就是中央倉庫的配置
在maven的聚合與繼承中我們說過,所有的maven專案都會繼承超級pom,具體的說,包含了下面配置的pom我們就稱之為超級pom
<repositories> <repository> <id>central</id> <name>Central Repository</name> <url>http://repo.maven.apache.org/maven2</url> <layout>default</layout> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories>
中央倉庫包含了絕大多數流行的開源Java構件,以及原始碼、作者資訊、SCM、資訊、許可證資訊等。一般來說,簡單的Java專案依賴的構件都可以在這裡下載得到。
2.2 私服
私服是一種特殊的遠端倉庫,它是架設在區域網內的倉庫服務,私服代理廣域網上的遠端倉庫,供區域網內的Maven使用者使用。當Maven需要下載構件的時候,它從私服請求,如果私服上不存在該構件,則從外部的遠端倉庫下載,快取在私服上之後,再為Maven的下載請求提供服務。我們還可以把一些無法從外部倉庫下載到的構件上傳到私服上。
Maven私服的 個特性:
1.節省自己的外網頻寬:減少重複請求造成的外網頻寬消耗
2.加速Maven構件:如果專案配置了很多外部遠端倉庫的時候,構建速度就會大大降低
3.部署第三方構件:有些構件無法從外部倉庫獲得的時候,我們可以把這些構件部署到內部倉庫(私服)中,供內部maven專案使用
4.提高穩定性,增強控制:Internet不穩定的時候,maven構建也會變的不穩定,一些私服軟體還提供了其他的功能
5.降低中央倉庫的負荷:maven中央倉庫被請求的數量是巨大的,配置私服也可以大大降低中央倉庫的壓力
當前主流的maven私服:
1.Apache的Archiva
2.JFrog的Artifactory
3.Sonatype的Nexus
三、遠端倉庫配置
配置遠端倉庫將引入新的配置元素:<repositories> <repository>
在<repositories>元素下,可以使用 <repository>子元素宣告一個或者多個遠端倉庫。
例子:
<repositories> <repository> <id>jboss</id> <name>JBoss Repository</name> <url>http://repository.jboss.com/maven2/</url> <releases> <updatePolicy>daily</updatePolicy><!-- never,always,interval n --> <enabled>true</enabled> <checksumPolicy>warn</checksumPolicy><!-- fail,ignore --> </releases> <snapshots> <enabled>false</enabled> </snapshots> <layout>default</layout> </repository> </repositories>
<updatePolicy>元素:表示更新的頻率,值有:never, always,interval,daily, daily 為預設值
<checksumPolicy>元素:表示maven檢查和檢驗檔案的策略,warn為預設值
出於安全方面的考慮,有時我們要對遠端倉庫的訪問進行認證,一般將認證資訊配置在settings.xml中:
<servers> <server> <id>same with repository id in pom</id> <username>username</username> <password>pwd</password> </server> </servers>
注:這裡的id必須與POM中需要認證的repository元素的Id一致。
如何將生成的專案部署到遠端倉庫
完成這項工作,也需要在POM中進行配置,這裡有新引入了一個元素:<distributionManagement>
distributionManagement包含了2個子元素:repository和snapshotRepository, 前者表示釋出版本構件的倉庫,後者表示快照版本的倉庫
這兩個元素都需要配置 id(該遠端倉庫的唯一標識),name,url(表示該倉庫的地址)
向遠端倉庫中部署構件,需要進行認證。配置同上
配置正確後執行: mvn clean deploy
正確的看待快照
之前我們在配置pom的時候,對於快照的配置都很謹慎,或者說很少用快照的版本,原因是它還很不穩定,極容易給我們的系統帶來未知的錯誤,讓我們很難查詢。其實快照版本也並不是一無是處,快照最大的用途是用在開發的過程中,尤其是有模組依賴的時候,比如說AB兩個模組同時開發,A依賴於B,開發過程中AB都是持續整合的開發,不斷的修改POM檔案和構建工程,這時候版本同步就成了一個很大的問題。使用快照就可以達到這一目的。
其實在快照版本在釋出的過程中,Maven會自動為構件以當前時間戳做標記,有了這個時間戳,我們就可以隨時找到最新的快照版本,這樣也就解決剛才說的 協作開發的問題。
至於A如何檢查B的更新,剛剛在講配置的時候說過,快照配置中有一個元素可以控制檢查更新的頻率------updatePolicy
我們也可以使用命令列加引數的形式強制執行讓maven檢查更新:
mvn clean install-U
maven到底是如何從倉庫中解析構件的呢?----maven從倉庫解析依賴的機制
1. 當依賴的範圍是system的時候,Maven直接從本地檔案系統解析構件
2. 根據依賴座標計算倉庫路徑後,嘗試直接從本地倉庫尋找構件,如果發現相應構件,則解析成功
3. 在本地倉庫不存在相應的構件情況下,如果依賴的版本是顯示的釋出版本構件,則遍歷所有的遠端倉庫,發現後下載使用
4. 如果依賴的版本是RELEASE或LATEST, 則基於更新策略讀取所有遠端倉庫的元資料,將其於本地倉庫的對應元資料合併後,計算出RELEASE或者LATEST的真實值,然後基於這個真實值檢查本地倉庫
5. 如果依賴的版本是SNAPSHOT, 則基於更新策略讀取所有遠端倉庫的元資料, 將其與本地倉庫的對應元資料合併後,得到最新快照版本的值,然後基於該值檢查本地倉庫或從遠端倉庫下載
6. 如果最後解析到的構件版本是時間戳格式的快照,則複製其時間戳格式的檔案 至 非時間戳格式,並使用該非時間戳格式的構件
注:一定要記得<release> <enabled> & <snapshot> <enabled> ,對於快照也是一樣
在POM的依賴宣告的時候不推薦使用LATEST & RELEASE, 在Maven3中也不再支援在外掛配置中使用LATEST & RELEASE, 如果不設定外掛版本,那麼最終版本和release一樣,
maven只會解析最新的釋出版本構建。
1.遠端倉庫的配置
在平時的開發中,我們往往不會使用預設的中央倉庫,預設的中央倉庫訪問的速度比較慢,訪問的人或許很多,有時候也無法滿足我們專案的需求,可能專案需要的某些構件中央倉庫中是沒有的,而在其他遠端倉庫中有,如JBoss Maven倉庫。這時,可以在pom.xml中配置該倉庫,程式碼如下:
1 <!-- 配置遠端倉庫 --> 2 <repositories> 3 <repository> 4 <id>jboss</id> 5 <name>JBoss Repository</name> 6 <url>http://repository.jboss.com/maven2/</url> 7 <releases> 8 <enabled>true</enabled> 9 <updatePolicy>daily</updatePolicy> 10 </releases> 11 <snapshots> 12 <enabled>false</enabled> 13 <checksumPolicy>warn</checksumPolicy> 14 </snapshots> 15 <layout>default</layout> 16 </repository> 17 </repositories>
repository:在repositories元素下,可以使用repository子元素宣告一個或者多個遠端倉庫。
id:倉庫宣告的唯一id,尤其需要注意的是,Maven自帶的中央倉庫使用的id為central,如果其他倉庫宣告也使用該id,就會覆蓋中央倉庫的配置。
name:倉庫的名稱,讓我們直觀方便的知道倉庫是哪個,暫時沒發現其他太大的含義。
url:指向了倉庫的地址,一般來說,該地址都基於http協議,Maven使用者都可以在瀏覽器中開啟倉庫地址瀏覽構件。
releases和snapshots:用來控制Maven對於釋出版構件和快照版構件的下載許可權。需要注意的是enabled子元素,該例中releases的enabled值為true,表示開啟JBoss倉庫的釋出版本下載支援,而snapshots的enabled值為false,表示關閉JBoss倉庫的快照版本的下載支援。根據該配置,Maven只會從JBoss倉庫下載釋出版的構件,而不會下載快照版的構件。
layout:元素值default表示倉庫的佈局是Maven2及Maven3的預設佈局,而不是Maven1的佈局。基本不會用到Maven1的佈局。
其他:對於releases和snapshots來說,除了enabled,它們還包含另外兩個子元素updatePolicy和checksumPolicy。
元素updatePolicy用來配置Maven從遠處倉庫檢查更新的頻率,預設值是daily,表示Maven每天檢查一次。其他可用的值包括:never-從不檢查更新;always-每次構建都檢查更新;interval:X-每隔X分鐘檢查一次更新(X為任意整數)。
元素checksumPolicy用來配置Maven檢查校驗和檔案的策略。當構建被部署到Maven倉庫中時,會同時部署對應的檢驗和檔案。在下載構件的時候,Maven會驗證校驗和檔案,如果校驗和驗證失敗,當checksumPolicy的值為預設的warn時,Maven會在執行構建時輸出警告資訊,其他可用的值包括:fail-Maven遇到校驗和錯誤就讓構建失敗;ignore-使Maven完全忽略校驗和錯誤。
2.遠端倉庫的認證
大部分公共的遠端倉庫無須認證就可以直接訪問,但我們在平時的開發中往往會架設自己的Maven遠端倉庫,出於安全方面的考慮,我們需要提供認證資訊才能訪問這樣的遠端倉庫。配置認證資訊和配置遠端倉庫不同,遠端倉庫可以直接在pom.xml中配置,但是認證資訊必須配置在settings.xml檔案中。這是因為pom往往是被提交到程式碼倉庫中供所有成員訪問的,而settings.xml一般只存在於本機。因此,在settings.xml中配置認證資訊更為安全。
1 <settings> 2 2 ... 3 3 <!--配置遠端倉庫認證資訊--> 4 4 <servers> 5 5 <server> 6 6 <id>releases</id> 7 7 <username>admin</username> 8 8 <password>admin123</password> 9 9 </server> 10 10 </servers> 11 11 ... 12 12 </settings>
上面程式碼我們配置了一個id為releases的遠端倉庫認證資訊。Maven使用settings.xml檔案中的servers元素及其子元素server配置倉庫認證資訊。認證使用者名稱為admin,認證密碼為admin123。這裡的關鍵是id元素,settings.xml中server元素的id必須與pom.xml中需要認證的repository元素的id完全一致。正是這個id將認證資訊與倉庫配置聯絡在了一起。
3.部署構件至遠端倉庫
我們使用自己的遠端倉庫的目的就是在遠端倉庫中部署我們自己專案的構件以及一些無法從外部倉庫直接獲取的構件。這樣才能在開發時,供其他對團隊成員使用。
Maven除了能對專案進行編譯、測試、打包之外,還能將專案生成的構件部署到遠端倉庫中。首先,需要編輯專案的pom.xml檔案。配置distributionManagement元素,程式碼如下:
1 <distributionManagement> 2 <repository> 3 <id>releases</id> 4 <name>public</name> 5 <url>http://59.50.95.66:8081/nexus/content/repositories/releases</url> 6 </repository> 7 <snapshotRepository> 8 <id>snapshots</id> 9 <name>Snapshots</name> 10 <url>http://59.50.95.66:8081/nexus/content/repositories/snapshots</url> 11 </snapshotRepository> 12 </distributionManagement>
distributionManagement包含repository和snapshotRepository子元素,前者表示釋出版本(穩定版本)構件的倉庫,後者表示快照版本(開發測試版本)的倉庫。這兩個元素都需要配置id、name和url,id為遠端倉庫的唯一標識,name是為了方便人閱讀,關鍵的url表示該倉庫的地址。
往遠端倉庫部署構件的時候,往往需要認證,配置認證的方式同上。
配置正確後,執行命令mvn clean deploy,Maven就會將專案構建輸出的構件部署到配置對應的遠端倉庫,如果專案當前的版本是快照版本,則部署到快照版本的倉庫地址,否則就部署到釋出版本的倉庫地址。
快照版本和釋出版本的區別請自行上百度查閱資料。
4.配置遠端倉庫的映象
如果倉庫X可以提供倉庫Y儲存的所有內容,那麼就可以認為X是Y的一個映象。換句話說,任何一個可以從倉庫Y獲得的構件,都能夠從它的映象中獲取。舉個例子,http://maven.oschina.net/content/groups/public/ 是中央倉庫http://repo1.maven.org/maven2/ 在中國的映象,由於地理位置的因素,該映象往往能夠提供比中央倉庫更快的服務。因此,可以配置Maven使用該映象來替代中央倉庫。編輯settings.xml,程式碼如下:
1 <mirrors> 2 <mirror> 3 <id>maven.oschina.net</id> 4 <name>maven mirror in China</name> 5 <url>http://maven.oschina.net/content/groups/public/</url> 6 <mirrorOf>central</mirrorOf> 7 </mirror> 8 </mirrors>
該例中,mirrorOf的值為central,表示該配置為中央倉庫的映象,任何對於中央倉庫的請求都會轉至該映象,使用者也可以使用同樣的方法配置其他倉庫的映象。id表示映象的唯一識別符號,name表示映象的名稱,url表示映象的地址。
關於映象的一個更為常見的用法是結合私服。由於私服可以代理任何外部的公共倉庫(包括中央倉庫),因此,對於組織內部的Maven使用者來說,使用一個私服地址就等於使用了所有需要的外部倉庫,這可以將配置集中到私服,從而簡化Maven本身的配置。在這種情況下,任何需要的構件都可以從私服獲得,私服就是所有倉庫的映象。這時,可以配置這樣的一個映象:
1 <!--配置私服映象--> 2 <mirrors> 3 <mirror> 4 <id>nexus</id> 5 <name>internal nexus repository</name> 6 <url>http://183.238.2.182:8081/nexus/content/groups/public/</url> 7 <mirrorOf>*</mirrorOf> 8 </mirror> 9 </mirrors>
該例中<mirrorOf>的值為星號,表示該配置是所有Maven倉庫的映象,任何對於遠端倉庫的請求都會被轉至http://183.238.2.182:8081/nexus/content/groups/public/。如果該映象倉庫需要認證,則配置一個id為nexus的認證資訊即可。
需要注意的是,由於映象倉庫完全遮蔽了被映象倉庫,當映象倉庫不穩定或者停止服務的時候,Maven仍將無法訪問被映象倉庫,因而將無法下載構件。
5.可用的Maven映象倉庫
1 <mirror> 2 <id>repo2</id> 3 <mirrorOf>central</mirrorOf> 4 <name>Human Readable Name for this Mirror.</name> 5 <url>http://repo2.maven.org/maven2/</url> 6 </mirror> 7 8 <mirror> 9 <id>ui</id> 10 <mirrorOf>central</mirrorOf> 11 <name>Human Readable Name for this Mirror.</name> 12 <url>http://uk.maven.org/maven2/</url> 13 </mirror> 14 15 16 <mirror> 17 <id>ibiblio</id> 18 <mirrorOf>central</mirrorOf> 19 <name>Human Readable Name for this Mirror.</name> 20 <url>http://mirrors.ibiblio.org/pub/mirrors/maven2/</url> 21 </mirror> 22 23 <mirror> 24 <id>jboss-public-repository-group</id> 25 <mirrorOf>central</mirrorOf> 26 <name>JBoss Public Repository Group</name> 27 <url>http://repository.jboss.org/nexus/content/groups/public</url> 28 </mirror> 29 30 <mirror> 31 <id>JBossJBPM</id> 32 <mirrorOf>central</mirrorOf> 33 <name>JBossJBPM Repository</name> 34 <url>https://repository.jboss.org/nexus/content/repositories/releases/</url> 35 </mirror>
上面的倉庫經過測試是可以訪問的。
6.倉庫搜尋服務地址
Sonatype Nexus:https://repository.sonatype.org/
MVNrepository:http://mvnrepository.com/
關於依賴的搜尋,個人覺得這兩個是最好用的。