在 Maven 中,任何一个依赖、插件或者项目构建的输出,都可以称之为构件。Maven 仓库能帮助我们管理构件(主要是JAR),它就是放置所有JAR文件(WAR,ZIP,POM等等)的地方。
Maven 仓库有三种类型:
- 本地仓库(
local
):Maven 的本地仓库,在安装 Maven 后并不会创建,它是在第一次执行 maven 命令的时候才被创建。运行 Maven 的时候,Maven 所需要的任何构件都是直接从本地仓库获取的。如果本地仓库没有,它会首先尝试从远程仓库下载构件至本地仓库,然后再使用本地仓库的构件。 - 中央仓库(
central
):Maven 中央仓库是由 Maven 社区提供的仓库,其中包含了大量常用的库。一般来说,简单的Java项目依赖的构件都可以在这里下载到,这个仓库由 Maven 社区管理,中央仓库包含了绝大多数流行的开源Java构件,不过国内访问太慢。 - 远程仓库(
remote
):如果 Maven 在中央仓库中也找不到依赖的文件,它会停止构建过程并输出错误信息到控制台。为避免这种情况,Maven 提供了远程仓库的概念,它是开发人员自己定制仓库(也就是自己公司搭建的私服)
,包含了所需要的代码库或者其他工程中用到的 jar 文件。
Maven 依赖仓库搜索顺序
当我们执行 Maven 构建命令时,Maven 开始按照以下顺序查找依赖的库:
- 步骤 1 - 在本地仓库中搜索,如果找不到,执行步骤 2,如果找到了则执行其他操作。
- 步骤 2 - 在中央仓库中搜索,如果找不到,并且有一个或多个远程仓库已经设置,则执行步骤 4,如果找到了则下载到本地仓库中以备将来引用。
- 步骤 3 - 如果远程仓库没有被设置,Maven 将简单的停滞处理并抛出错误(无法找到依赖的文件)。
- 步骤 4 - 在一个或多个远程仓库中搜索依赖的文件,如果找到则下载到本地仓库以备将来引用,否则 Maven 将停止处理并抛出错误(无法找到依赖的文件)。
备注:Maven 中央仓库默认在国外, 目前国内使用很慢,Maven源码中默认是访问中央仓库,所以国常使用镜像,来完成jat包的依赖,最直接的方式在
Settings.xml
中设置mirror
,使用阿里等一些国内主流的镜像仓库替代远程中央镜像。
Maven仓库配置方式
第一种场景:个人开发,直接使用国内镜像仓库替换Maven中央仓库,操作比较简单,直接在Maven安装目录的settings.xml
文件中进行全局配置即可,以阿里云的镜像为例:
<!--使用阿里云镜像仓库替换Maven默认的中央仓库 -->
<mirrors>
<!--
设置多个mirror镜像,镜像只会执行第一个位置mirror,最好是选取一个镜像下载比较快的放在第一个。
-->
<mirror>
<!--镜像的唯一标识,在mirror标签中,其实没啥用 -->
<id>alimaven</id>
<!--仓库描述,随意写 -->
<name>阿里云仓库地址</name>
<!--国内镜像仓库地址,这个很重要不能错-->
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
说明:central
其实为Maven中央仓库的标识,Maven源码内默认的是中央仓库地址,这段配置的意思可以理解为替换Maven中央仓库地址为阿里云仓库。mirrorOf
主要的作用可以理解为拦截,覆盖并重定向新的指定的url镜像仓库地址。
第二种场景:公司开发,一般公司都会使用nexus
搭建自己的私有仓库,它极大的简化了本地内部仓库的维护和外部仓库的访问。毕竟有些涉及到自研发的jar包,这部分jar只是公司内部研发,拱各个项目组共同使用,这种也比较简单。
<!--使用xx公司私有仓库替换Maven默认的中央仓库 -->
<mirrors>
<mirror>
<!--自己公司的镜像的唯一标识,在mirror标签中,其实没啥用:如xiaoyaziyun -->
<id>xiaoyaziyun</id>
<!--仓库描述,随意写 -->
<name>小鸭子公司私有仓库地址</name>
<!--小鸭子公司私有仓库地址,这个很重要不能错-->
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<!--`central`为Maven中央仓库的标识,替换Maven源码内默认的是中央仓库地址-->
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
参考:使用Nexus搭建Maven私服
第三种场景: 项目配置公司私服,并且配置国内镜像仓库地址。
这个得先按照配置第一场景,配置Settings.xml
,然后在项目总pom.xml
中增加以下配置:
<repositories>
<repository>
<!--公司镜像的唯一标识,这个配置要注意,不能与mirrorOf配置的相同,不然会被拦截,重定向到外网的镜像仓库 -->
<id>nexus</id>
<!--仓库描述,随意写 -->
<name>Team Nexus Repository</name>
<!--小鸭子公司私有仓库地址,这个很重要不能错-->
<url>http://xiaoyaziyun.com:8081/nexus/content/groups/public</url>
</repository>
</repositories>
mirror和repository的关系、区别
要分清楚mirror
与epository
关系、区别,要先知道Maven在下载依赖jar包时,读取配置文件顺序:
一个java项目通过Maven自动下载依赖时,会读取三个配置文件,分别是:
- 项目下
pom.xml
文件中<repository></repository>
配置,多个repository
时,按照从上往下的顺序读取配置。 - 用户录下的
.m2/settings.xml
内的<mirror></mirror>
(.m2它是在第一次执行 maven 命令的时候才被创建,不过一般开发都会自定义路径,可忽略)。 - Maven安装目录
/conf
文件夹下的,全局配置settings.xml
(重要)。
三者的级先是pom.xml
>/用户/.m2/settings.xml
>/maven安装目录/conf/settings.xml
,如果要设置全局Maven仓库配置,需要在Maven安装目录/conf
下找到settings.xml
来修改。
上面也提到mirror
相当于一个拦截器,它会拦截Maven对remote repository
(远程仓库)的相关请求,把请求里的remote repository
地址,重定向到mirror
里配置的地址。这个拦截的就是pom.xml中设置的<repository></repository>
配置
1、在mirrorOf
与repository
中的Id
相同的时,优先是使用mirror
的地址。
2、当mirrorOf
配置为*
(通配符)的时,就是拦截所有repository
配置。
3、存在多个mirror
配置的时候mirrorOf
等于*
放到最后,但是官网给的说法是,当配置多个mirror
时,只有第一个生效,但是我自己项目测试时候,配置多个时候,还是有影响的,懒得细查了。
4、只配置mirrorOf为central的时候可以不用配置repository
mirrorOf
标签还支持更高级的镜像配置:
配置方式 | 作用描述 |
---|---|
external:* | 表示不在本地仓库的文件才从重定向的镜像仓库获取 |
repo,repo1 | 表示拦截远程仓库 repo 和 repo1访问,重定向到指定url镜像仓库获取 |
*,!repo1 | 表示所有远程仓库都从指定url镜像仓库获取,除 repo1 远程仓库以外 |
* | 表示所用远程仓库都从指定url镜像仓库获取 |
总结:Maven获取pom.xml
里的repository
集合,然后在settings.xml
里找mirrors
元素,如果repository
的id
和mirror的mirrorOf
的值相同,则该mirror
替代该repository
,如果该repository
找不到对应的mirror
,则使用其本身指定的仓库地址,依此可以得到最终起作用的远程仓库集合。
仓库优先级
本地仓库 > 私服 (profile)> 远程仓库(repository)和 镜像 (mirror) > 中央仓库 (central)
Maven的settings.xml
文件里面不仅有mirror,还有
proxy、
server、
repository`的配置,在配置仓库地址的时候容易混淆:
-
proxy
是服务器不能直接访问外网时需要设置的代理服务,不常用。 -
serve
是服务器要打包上传到私服时,设置私服的鉴权信息,如本地的jar包上传到私服,就要在这里设置密码。 -
profiles
上面提到mirror
,配置多个只会一个有效,如果需要多仓库配置,可以在profiles节点下配置多个profile,但是配置需要激活,特别麻烦,也不常用。 -
mirror
是用于拦截并替代指定id镜像地址。
总结: 在有私服的情况下,最好是直接在Setings
设置全局拦截,把所有的仓库指向公司的私服,因为nexus
也会配置国内镜像地址,当jar不存在是,它会连接外网进行下载,也就是按照第一场景设置。
网友评论