Maven 仓库

在之前的章节中,我们分别介绍了 Maven 中的工程对象模型(POM)以及 Maven 的依赖管理,但是,这个时候,我们势必会有一个疑问,当我找到一个依赖的坐标后,只需要将该坐标放入到我项目的 POM 文件当中,这个依赖就算是被引入了,那这个依赖是从哪里来的呢?

在本节中,我们就带着这个疑问来学习 Maven 的仓库,了解如何使用 Maven 仓库。

1. 什么是 Maven 仓库

我们先想象一下,如果没有 Maven,我们在开发不同项目的时候,如果需要依赖同一个 jar 包,那么就需要分别在两个不同项目中将这个 jar 包引入进去,对于一个程序员来说,这样的做法显然是不合理的,不仅需要我们手动到处复制,而且会多占用我们的磁盘空间。

那这个时候,Maven 仓库就出现了。我们通常把依赖称为构件,每一个构件都有自己唯一的坐标,基于这种模式,我们就可以把这些构件存放在一个指定的位置–Maven仓库当中,然后通过其坐标来寻找该构件。

在我们学习或者实际开发过程中,只需要在我们的项目当中声明依赖的坐标,在项目编译的或者打包的过程中,Maven 会自动从仓库中去寻找该构件,这样就不需要我们在本地存储这个依赖了。

2. 仓库的分类

对于 Maven 来说,主要的仓库种类可以分为两种,一种是本地仓库,另一种是远程仓库。而在远程仓库当中呢,又可以分为中央仓库,私服和其他的公共仓库。
图片描述

2.1 本地仓库

在我们声明的 MAVEN_HOME 路径下,找到 conf\settings.xml,其中可以看到 Maven 的本地仓库路径配置:

从上图我们可以看到,Maven 的默认本地仓库路径是在 ${user.home}/.m2/repository,我们为了方便将其修改为了 D:\repo

2.2 中央仓库

Maven 中默认配置了中央仓库,我们可以在超级 POM 里面找到对应的配置。

这个仓库是由 Maven 社区来维护的,里面存放了绝大多数开源软件的包,并且是作为 Maven 的默认配置,不需要开发者额外配置。另外为了方便查询,还提供了一个查询地址,开发者可以通过这个地址更快的搜索需要构件的坐标。

2.3 其他远程仓库

有了中央仓库,我们为什么还需要其他的远程仓库呢?

  • 我们要找的构件可能不存在于中央仓库中;
  • 由于某些原因,访问中央仓库的速度相对较慢。

这种时候,我们就可以选择一个使用起来相对方便的远程仓库来配置,大大提高了我们的开发效率。

国内常用的 Maven 仓库:

  • 阿里云镜像:

    <mirror>
        <id>alimaven</id>
        <name>aliyun maven</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
        <mirrorOf>central</mirrorOf>
    </mirror>
    
  • 阿里巴巴镜像:

    <mirror>
        <id>ibiblio</id>
        <mirrorOf>central</mirrorOf>
        <name>Human Readable Name for this Mirror.</name>
        <url>http://mirrors.ibiblio.org/pub/mirrors/maven2/</url>
    </mirror>
    
  • repo2 镜像:

    <mirror>  
        <id>repo2</id>  
        <mirrorOf>central</mirrorOf>  
        <name>Human Readable Name for this Mirror.</name>  
        <url>http://repo2.maven.org/maven2/</url>  
    </mirror>
    

我们可以将对应的仓库的镜像配置到 settings.xml 文件中的 mirrors 节点中即可。如下图所示,我们配置了阿里云的镜像。

2.4 私服

私服也是属于远程仓库的一种,相对公共仓库而言属于某个公司或者某个开发团队私有的远程仓库。通常部署在某个局域网内,提供局域网的内部用户使用。

那私服有什么好处呢?

  • 更快的下载速度:由于是局域网内部的请求,因此下载构件的速度是可以保证的;
  • 更稳定的构建:想象一下,如果我们依赖某个外部的远程仓库,当这个仓库出现不可能用的情况,哪怕是网络的波动,都有可能会造成我们的构建失败;
  • 部署第三方构件:如果一个公司使用了微服务架构,那么公共仓库是肯定没办法获取这些私有的构件的。

当我们需要一个构件的时候,Maven 会先去请求私服,如果发现私服中,没有该构件,那么就会去配置了的远程仓库中寻找,并且缓存到我们的私服中,为后续的下载请求提供服务。

3. Maven 的依赖解析顺序

我们知道了 Maven 通过坐标去仓库中寻找对应的构件,那么这个机制的原理是怎么样的呢?

Maven 在寻找需要的依赖的时候,会遵照下面的顺序:

  1. 如果构件的依赖范围是 system,Maven 会直接从本地的文件系统来解析该构件;
  2. 根据配置的依赖坐标,在本地仓库中寻找该构件,如果能够搜索到,则解析成功;
  3. 如果本地仓库没有搜索到,那么就会去已经配置了的远程仓库中搜索该构件,搜索到后,下载到本地仓库中,提供项目使用;
  4. 如果依赖的版本是 RELEASE 或 LATEST,那么就会根据更新策略去读取所有远程仓库中的元数据信息(groupId/artifactId/maven-metadata.xml),并且与本地仓库中对应的元数据合并后,计算出真实值,再将其下载到本地仓库中;
  5. 如果依赖的版本是 SNAPSHOT,那么就会根据更新策略去读取所有远程仓库中的元数据信息(groupId/artifactId/version/maven-metadata.xml),并且与本地仓库中对应的元数据信息合并后,得到最新的快照版本值,根据这个值去寻找对应的依赖;
  6. 解析出的快照版本一般是带有时间戳的,下载下来后,会将该时间戳删掉,以无时间戳的形式来使用。

4. 小结

在本节中,我们介绍了什么是 Maven 仓库,主要的仓库分类以及不同仓库的特点。最后我们还介绍了从 Maven 仓库中的依赖解析机制。