业务需求开发的时候,我们总是会遇到拉不到依赖包的情况。此时如果不清楚 Maven 拉取依赖包的原理,那么很可能找不到问题所在。今天树哥就带大家了解下 Maven 拉包的原理,让你在遇到问题的时候能快速解决!

三种仓库

在 Maven 中,仓库指的是存放代码构建的一个位置。从分类上来说,Maven 仓库有两种类型,分别是:

  • 本地仓库(Local)
  • 远程仓库(Remote)

本地仓库,是存在于本地的一个仓库,它用来缓存下载的依赖包。这样就不用每次都通过网络去拉取依赖包了,提高了依赖拉取速度,减轻了仓库服务器的压力。

远程仓库,如其名字所述,其实位于远程服务器的一个仓库。例如有些公司自己对外开放了一些 API,需要将这些 API 的依赖开放出去,这时候就可以将 API 的 Jar 包放到公司自己的远程仓库中。公司的客户可以通过连接该仓库下载 Jar 包。例如你们公司开发了自己的基础工具类,并将其打成了一个 Jar 包。此时你可以将该 Jar 包部署到公司自己的远程仓库中,公司其他开发伙伴配置该远程仓库,从而可以拉取到该 Jar 包依赖。

在网上其他资料中,还会提到 Maven 仓库有另一个类型 —— 中央仓库(Central)。但在我看来,中央仓库其实是一个特殊的远程仓库。 它的特殊之处在于,它是 Maven 官方提供的,其中包括了大量常用的库,基本上大多数的依赖包都可以在这里找到。另外一个特殊之处在于,中央仓库的地址是内置在 Maven 源码中的,即默认会向中央仓库拉取依赖,这个在后续的依赖搜索顺序中会讲到。

而我们经常说的私服,其实也是一个特殊的远程仓库,其特殊之处在于:它只对公司内部开放,方便存放一些本团队创建的开发库。我们经常说的阿里云 Maven 库,其实就是一个远程仓库,只不过其是对所有人开放罢了。

依赖搜索顺序

弄懂了仓库的类型,我们继续来了解下依赖的搜索顺序。

我们在开发过程中找不到依赖包,有多种原因,例如:

  • 依赖包确实没有放到远程仓库
  • 仓库配置有问题
  • 等等

为了弄清楚到底是什么原因导致依赖找不到,我们需要了解 Maven 是如何找一个依赖的。简单来说,Maven 搜索依赖的算法如下:

  1. 首先,在本地仓库搜索,如果找不到则继续下一步。
  2. 接着,在中央仓库搜索,如果找不到则继续下一步。
  3. 最后,在远程仓库中搜索,如果找不到则抛出错误。如果没有设置远程仓库,那么抛出错误。如果找到了依赖,那么就下载到本地仓库缓存。

简单地说,Maven 搜索遵循简单的顺序 —— 本地仓库 -> 中央仓库 -> 远程仓库。弄明白了这个依赖搜索顺序,可以帮助我们更好地排查问题。但这可能还不够,我们还需要搞清楚 Maven setting.xml 中的一些配置信息,从而可以排查是否是配置出现了问题。例如:有时候我们配置了 mirror 镜像,会把对某个仓库的请求转发到另一个仓库,这时候你要是不懂 mirror 配置,你就找不到问题所在了。

配置信息

关于仓库的一些常见的配置项有:

  • repositories
  • mirror
  • server
  • 等等

下面我们将一个个讲解他们的作用。

repositories 标签

repositories 标签用于定义远程仓库,其配置范例如下所示:

<repositories>
<repository>
<!--公司镜像的唯一标识,这个配置要注意,不能与mirrorOf配置的相同,不然会被拦截,重定向到外网的镜像仓库 -->
<id>nexus</id>
<!--仓库描述,随意写 -->
<name>xxxx</name>
<!-- 公司私有仓库地址,这个很重要不能错-->
<url>http://xxx:8081/nexus/content/groups/public</url>
<!-- 是否开启 releases 包的下载及更新策略 -->
<releases>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy>
</releases>
<!-- 是否开启 snapshots 包的下载及更新策略 -->
<snapshots>
<enabled>false</enabled>
<checksumPolicy>warn</checksumPolicy>
</snapshots>
<layout>default</layout>
</repository>
</repositories>

repositories 标签既可以在 setting.xml 文件配置,也可以在 pom.xml 文件中配置。Maven 在拉取依赖的时候,是按照声明的顺序从上到下去对应的远程仓库拉取依赖的。

mirror 标签

mirror 标签用于定义仓库镜像,其相当于一个拦截器。当 mirror 的 mirrorOf 值与 repository 的 id 相同时,repository 定义的仓库会被拦截,转而使用 mirror 中定义的仓库地址。配置范例如下:

<!--使用xx公司私有仓库替换Maven默认的中央仓库 -->
<mirrors>
<mirror>
<!--自己公司的镜像的唯一标识,在mirror标签中,其实没啥用:如xiaoyaziyun -->
<id>xiaoyaziyun</id>
<!--仓库描述,随意写 -->
<name>xx公司私有仓库地址</name>
<!--xx公司私有仓库地址,这个很重要不能错-->
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<!--`central`为Maven中央仓库的标识,替换Maven源码内默认的是中央仓库地址-->
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>

如上图配置所示,Maven 会用 http://maven.aliyun.com/nexus/content/groups/public/ 这个仓库镜像替换 Maven 中央仓库,其中 central 是 Maven 中央仓库的 ID 标识。我们经常说用阿里云的 Maven 仓库可以提速,其实就是使用这种方法实现的。

server 标签

大部分远程仓库无须认证就可以访问,但我们自己搭建的 Maven 仓库,处于安全方面的考虑,我们会设置访问权限。此时,我们需要在 setting.xml 文件中配置 server标签。配置示例如下代码所示:

<settings>
<!--配置远程仓库认证信息-->
<servers>
<server>
<id>shuyi-tech-repo</id>
<username>admin</username>
<password>admin123</password>
</server>
</servers>
</settings>

上面的配置为 repository id 为 shuyi-tech-repo 的远程仓库配置了用户名和密码,其中用户名为 admin,密码为 admin123。这里通过 server.idreposiroty.id 标签将认证信息与仓库绑定在一起,因此在配置的时候需要保持这两个信息一致,否则可能导致访问失败。

其他标签

  • proxy 标签:服务器不能直接访问外网时需要设置的代理服务,不常用。
  • profiles 标签:上面提到mirror,配置多个只会一个有效,如果需要多仓库配置,可以在profiles节点下配置多个profile,但是配置需要激活,特别麻烦,也不常用。

配置文件优先级

对于 Maven 来说,我们会看到有多个配置文件:

  • 项目 pom.xml 文件
  • .m2/settings.xml 文件
  • Maven 安装目录 /conf/settings.xml 文件

如果一个配置同时存在于多个位置,那么到底以哪个为准呢?简单地说,这几个配置文件的优先级是怎样的呢?如果没搞懂这个问题,那么我们排查问题的时候可能会一团糟。

其实三者的优先级是 pom.xml >/用户/.m2/settings.xml>/maven安装目录/conf/settings.xml。如果要设置全局 Maven 仓库配置,需要在 Maven 安装目录 /conf 下找到 settings.xml 来修改。

参考资料

一文带你弄懂 Maven 拉包原理的更多相关文章

  1. 一文带你弄懂 CDN 技术的原理

    对于 CDN 这个东西,相信大家都有耳闻,感觉既陌生但又熟悉.最近深入了解了一下 CDN,这才发现原来 CDN 如此重要!今天就跟大家科普一下 CDN 是什么,以及为啥要有 CDN,最后再讲一下 CD ...

  2. 一文带你弄懂 JVM 三色标记算法!

    大家好,我是树哥. 最近和一个朋友聊天,他问了我 JVM 的三色标记算法.我脑袋一愣发现竟然完全不知道!于是我带着疑问去网上看了几天的资料,终于搞清楚啥事三色标记算法,它是用来干嘛的,以及它和 CMS ...

  3. 一文带你读懂什么是vxlan网络

    一个执着于技术的公众号 一.背景 随着云计算.虚拟化相关技术的发展,传统网络无法满足大规模.灵活性要求高的云数据中心的要求,于是便有了overlay网络的概念.overlay网络中被广泛应用的就是vx ...

  4. 一文带你读懂zookeeper在大数据生态的应用

    一个执着于技术的公众号 一.简述 在一群动物掌管的世界中,动物没有人类聪明的思想,为了保持动物世界的生态平衡,这时,动物管理员-zookeeper诞生了. 打开Apache zookeeper的官网, ...

  5. 实战 | 一文带你读懂Nginx反向代理

    一个执着于技术的公众号 前言 在前面的章节中,我们已经学习了nginx基础知识: 给小白的 Nginx 10分钟入门指南 Nginx编译安装及常用命令 完全卸载nginx的详细步骤 Nginx 配置文 ...

  6. 一文带你看懂Java中的Lock锁底层AQS到底是如何实现的

    前言 相信大家对Java中的Lock锁应该不会陌生,比如ReentrantLock,锁主要是用来解决解决多线程运行访问共享资源时的线程安全问题.那你是不是很好奇,这些Lock锁api是如何实现的呢?本 ...

  7. 从源码入手,一文带你读懂Spring AOP面向切面编程

    之前<零基础带你看Spring源码--IOC控制反转>详细讲了Spring容器的初始化和加载的原理,后面<你真的完全了解Java动态代理吗?看这篇就够了>介绍了下JDK的动态代 ...

  8. Python——五分钟带你弄懂迭代器与生成器,夯实代码能力

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是周一Python专题,给大家带来的是Python当中生成器和迭代器的使用. 我当初第一次学到迭代器和生成器的时候,并没有太在意,只是觉 ...

  9. 【springcloud】一文带你搞懂API网关

    作者:aCoder2013 https://github.com/aCoder2013/blog/issues/35 前言 假设你正在开发一个电商网站,那么这里会涉及到很多后端的微服务,比如会员.商品 ...

  10. 一文带你看懂cookie,面试前端不用愁

    本文由云+社区发表 在前端面试中,有一个必问的问题:请你谈谈cookie和localStorage有什么区别啊? localStorage是H5中的一种浏览器本地存储方式,而实际上,cookie本身并 ...

随机推荐

  1. 排查占用cpu最高线程

  2. list tuple dic set的区别

    list是可变的(可以在list里边添加删除替换内容) 声明时用[ ] tuple和list非常类似,但是tuple一旦初始化就不能修改  ,声明时用() classmates = ('Michael ...

  3. input类型为number仍可以输入e,+,-解决方法

    <input type="number" onKeypress="return(/[\d\.]/.test(String.fromCharCode(event.ke ...

  4. MATLAB画图自动确定坐标范围(GUI)

    今天在用MATLAB做我的毕设的时候碰到一个很纠结的问题,之所以说纠结是因为我觉得这个问题很简单,可是一时半会就是弄不出来(ー`´ー).鼓捣了半个小时左右吧,终于搞出来了.下面做个纪念: 问题描述 在 ...

  5. 错误小记录: python取余操作

    -23 % 3 >>>1 23%-3 >>>-1 -23%-3 >>>-2 在计算机语言中,同号的整数运算,所有语言都遵循尽量让商小的原则,所以 ...

  6. 怎样清空 DNS 缓存?

    在 Windows 下命令行执行:ipconfig /flushdns 在 macOS 下执行命令:sudo killall -HUP mDNSResponder

  7. C语言的导数和积分

    用C进行导数和积分的运算 进行求导 设一个dx,利用f(x)-f(x-dx)/dx或f(x)-f(x+dx)/dx进行计算. float qd(float x) { float dx=0.01,y; ...

  8. selenium--- 数据驱动测试 ddt

    通过使用数据驱动测试的方法,可以在需要验证多组数据的测试场景中,使用外部数据源实现对输入值和期望值的参数化,从而避免在测试中仅使用硬编码的数据.将测试数据和测试脚本分离开,使得测试脚本在不同数据集合下 ...

  9. 实验二:Open vSwitch虚拟交换机实践

    基础要求提交 a) /home/用户名/学号/lab2/目录下执行ovs-vsctl show命令.以及p0和p1连通性测试的执行结果截图: b) /home/用户名/学号/lab2/目录下开启Min ...

  10. mysql索引类型详解

    转载网址: http://c.biancheng.net/view/7897.html