MAVEN版本:
3.6.1
參考: http://www.voidcn.com/article/p-kufgcswl-mv.html
maven 是什麼
balabala…
maven倉庫 — repository
本地倉庫 VS 遠程倉庫
運行Maven的時候,Maven所需要的任何構件都是直接從本地倉庫
獲取的。
如果本地倉庫沒有,它會首先嚐試從遠程倉庫下載構件至本地倉庫,然後再使用本地倉庫的構件。
本地倉庫
- Maven缺省的本地倉庫地址爲
${user.home}/.m2/repository
。也就是說,一個用戶會對應的擁有一個本地倉庫。 - 你也可以自定義本地倉庫的位置,修改
${user.home}/.m2/settings.xml
中如下內容:
<settings>
<localRepository>E:\maven\repository</localRepository>
</settings>
- 你還可以在運行時指定本地倉庫位置:
mvn clean install -Dmaven.repo.local=YOUR_LOCAL_REPO
遠程倉庫
瞭解了本地倉庫,接着瞭解一下Maven缺省的遠程倉庫,即Maven中央倉庫。
這個Maven中央倉庫是在哪裏定義的呢?
${M2_HOME}/lib/maven-model-builder-3.6.1.jar
,打開該文件,能找到超級POM:/org/apache/maven/model/pom-4.0.0.xml
,定義來默認對中央倉庫:central
.
私服
通常,公司內部會搭建一個內部對maven倉庫(私服
),我們通常通過私服來獲取構件,結構如下圖:
Nexus
是比較常用的Maven私用服務器。
圖片引用自: https://blog.csdn.net/liujiahan629629/article/details/39272321
在pom中配置遠程倉庫
<project>
<!-- repositories 下面可以配置多個repository, 每個repository有一個唯一的ID-->
<repositories>
<repository>
<id>aliyun</id>
<name>aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases><enabled>true</enabled></releases>
<!--snapshots默認是關閉的,需要開啓 -->
<!--禁止從公共倉庫下載snapshot構件是推薦的做法,因爲這些構件不穩定,且不受你控制,你應該避免使用。
但是如果是私服倉庫,可以激活snapshot的支持 -->
<snapshots><enabled>true</enabled></snapshots>
</repository>
<repository>
<id>huawei</id>
<name>華爲雲</name>
<url>https://repo.huaweicloud.com/repository/maven/</url>
<releases><enabled>true</enabled></releases>
</repository>
</repositories>
<!-- pluginRepositories,這是配置Maven從什麼地方下載插件, 同repositories -->
<pluginRepositories>
<pluginRepository>
<!-- id可以與 repositories中重複 -->
<id>aliyun</id>
</pluginRepository>
</pluginRepositories>
</project>
setting.xml中配置遠程倉庫
我們知道了如何在POM中配置遠程倉庫,還可以在setting.xml
中配置倉庫。
但是<settings>標籤內並
並不支持<repositories>及<pluginRepositories>
, 我們需要利用<profile>
來配合使用,最終通過<activeProfiles>
來激活指定的<profile>
.
<settings>
<profiles>
<profile>
<id>dev</id>
<repositories>
<repository>
</repository>
</repositories>
</profile>
<profile>
<id>test</id>
<repositories>
<repository>
</repository>
</repositories>
</profile>
<profile>
<id>prod</id>
<repositories>
<repository>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>dev</activeProfile>
<activeProfile>test</activeProfile>
</activeProfiles>
</settings>
倉庫的優先級
首先申明一個前提:
本地倉庫
的優先級最高,接下來我們在以實際上不存的構件爲前提下進行測試。
前文瞭解到,可以在多個地方,每個地方又可以配置多個倉庫,那麼倉庫加載的優先級是如何的呢?
下面我們來綜合分析下,假設我們引用一個不存在的構件:
<dependencies>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit</artifactId>
<!-- 指定一個不存在的構件-->
<version>x.y.z</version>
</dependency>
</dependencies>
僅在pom中配置多個repository
<repositories>
<repository>
<id>huawei</id>
<name>華爲雲</name>
<url>https://repo.huaweicloud.com/repository/maven/</url>
<releases><enabled>true</enabled></releases>
</repository>
<repository>
<id>aliyun</id>
<name>阿里雲</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases><enabled>true</enabled></releases>
<!--snapshots默認是關閉的,需要開啓 -->
<!--禁止從公共倉庫下載snapshot構件是推薦的做法,因爲這些構件不穩定,且不受你控制,你應該避免使用。
但是如果是私服倉庫,可以激活snapshot的支持 -->
<snapshots><enabled>false</enabled></snapshots>
</repository>
</repositories>
執行命令:mvn clean install -U
來強制更新,結果如下:
通過執行結果,可以推測出:在<repositories>
中定義的順序先後進行加載,最後再嘗試加載中央倉庫。
同事在setting.xml中配置多個倉庫
在前文的基礎上,在setting.xml
中配置多個profile
,且同時激活多個profile
,配置如下:
<settings>
<profiles>
<profile>
<id>dev</id>
<repositories>
<!--省略 repository url相關配置,下同 -->
<repository><id>dev2</id> </repository>
<repository><id>dev1</id></repository>
</repositories>
</profile>
<profile>
<id>test</id>
<repositories>
<repository> <id>test1</id> </repository>
<repository> <id>test2</id> </repository>
</repositories>
</profile>
<profile>
<id>prod</id>
<repositories>
<repository> <id>prod1</id> </repository>
<repository> <id>prod2</id> </repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>test</activeProfile>
<activeProfile>dev</activeProfile>
</activeProfiles>
</settings>
執行命令:mvn clean install -U
來強制更新,結果如下:
可以得出結論:
- 首先,加載
settings.xml
中<activeProfiles>
激活<activeProfile>
,且<activeProfile>
會按照定義的先後順序加載<activeProfile>
內部的<repositories>
中的多個倉庫,同樣按照定義的先後順序加載
- 然後, 加載
pom.xml
中的倉庫(按順序加載) - 最後, 會從中央倉庫嘗試加載。
maven鏡像-mirror
通常,有很多依賴(構件)在中央倉庫(境外
),由於衆所周知的原因會下載的很慢,或者壓根下載不到,我們可以通過代理(鏡像)
來實現.
通過鏡像的配置mirrorOf
,覆蓋指定倉庫的url
,從而實現代理
的功能。
mirror並不會影響倉庫的加載順序,而是在確定了倉庫之後,改變倉庫的請求地址!
配置多個mirror以及鏡像的優先級
注意,鏡像只能在
settings.xml
中配置
在前文的基礎上,增加mirror
配置, 同時爲central中央倉庫
添加 三個鏡像:
<settings>
<mirrors>
<mirror>
<id>mirror2</id>
<!-- 通過mirrorOf 用自身的url 覆蓋指定倉庫的url-->
<mirrorOf>central</mirrorOf>
<!-- <url>https://repo1.maven.org/maven2</url> -->
<!-- 這樣就不允許直接從中央倉庫下載jar包, 必須通過配置的url中下載jar-->
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
<mirror>
<id>mirror1</id>
<mirrorOf>central</mirrorOf>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
<mirror>
<id>mirror3</id>
<mirrorOf>central</mirrorOf>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
</mirrors>
</settings>
執行mvn clean install -U
,強制更新:
從結果可以得出結論:如果一個倉庫匹配到多個mirror,會按照先後順序進行匹配
,僅第一個匹配到的mirror有效.
mirrorOf -配符
通過鏡像的配置mirrorOf
,覆蓋指定倉庫的url
,mirrorOf 中除了指定具體的repository配置對id
,maven還支持更高級的用法:
*
: 所有遠程倉庫都從該鏡像獲取*,!repo1
: 除repo1
遠程倉庫以外的所有倉庫都從該鏡像獲取repo1,repo2
:repo1
和repo2
倉庫都從該鏡像獲取external:*
:不在本地倉庫的文件才從該鏡像獲取
deploy到遠程倉庫。
mvn install
會將項目生成的構件安裝到本地Maven倉庫,mvn deploy
用來將項目生成的構件分發到遠程Maven倉庫
。
本地Maven倉庫的構件只能供當前用戶使用,在分發到遠程Maven倉庫(通常是私服)之後,你的同事才能使用到你發佈的構建。
pom中配置-distributionManagement
<!-- 部署配置-->
<distributionManagement>
<snapshotRepository>
<id>nexus-snapshot</id>
<url>http://your_company_nexus_host:port/repository/maven-snapshots/</url>
</snapshotRepository>
<repository>
<id>nexus-release</id>
<url>http://your_company_nexus_host:port/repository/maven-releases</url>
</repository>
</distributionManagement>
Maven區別對待release
版本的構件和snapshot
版本的構件,
- snapshot
爲開發過程中的版本,實時,但不穩定,會部署到<snapshotRepository>
倉庫。
- release
版本則比較穩定,會部署到<repository>
倉庫。
Maven會根據你項目的版本號
來判斷將構件分發到哪個倉庫。
- 當版本號符合
*-SNAPSHOT
形式時,會部署到<snapshotRepository>
,注意**-SNAPSHOT(大小寫不敏感,但是 - 必須要有)** - 其他版本號,會部署到
<repository>
setting.xml配置servers
一般來說,分發構件到遠程倉庫需要認證,如果你沒有配置任何認證信息,你往往會得到401錯誤。
<!-- 服務發佈到目標私服的用戶名密碼,
id對應pom.xml中的distributionManagement.repository.id 或者 distributionManagement.snapshotRepository.id一致-->
<servers>
<server>
<id>nexus-snapshot</id>
<username>deployment</username>
<password>deployment123</password>
</server>
<server>
<id>nexus-release</id>
<username>publish</username>
<password>publish123</password>
</server>
</servers>
最後使用mvn deploy
部署即可。