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私用服务器。图片引用自:
在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:*
:不在本地仓库的文件才从该镜像获取
mirroor.id – 401 – 20240713 补充
假设有如下配置,遇到401问诶
<mirrors>
<mirror>
<id>secureArtifactory</id>
<mirrorOf>repo1,repo2.....,central,maven-central</mirrorOf>
<url>https://aaa.bbb.com/artifactory/ccc-group</url>
</mirror>
</mirrors>
遇到401 错误from/to secureArtifactory (https://aaa.bbb.com/artifactory/ccc-group): authentication failed for https://aaa.bbb.com/artifactory/ccc-group/com/xxx/yyy/zzz/4.0.286/zzz-4.0.286.pom, status: 401 Unauthorized -> [Help 1]
则说明访问mirror.id=secureArtifactory 需要配置token认证信息, 同repository类似,需要配置一个同名的server信息即可。
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
部署即可。