本文是系列文章《Maven 源码解析:依赖调解是如何实现的?》第七篇,也是最后一篇,主要做个总结。请按顺序阅读其他系列文章,系列文章总目录参见:hhttps://www.cnblogs.com/xiaoxi666/p/15583241.html

总结

在本系列文章中,我们搭建了一个简单的多模块项目,以实验的形式,从源码角度解析了四种依赖调节原则。涉及到了传递依赖的两种调解原则、一种同文件内的覆盖原则,以及 dependencyManagement 依赖锁定原则。其中,传递依赖的两种调解原则涉及到 NearestConflictResolver 冲突调解器;而同文件内的覆盖原则最简单,就是简单的 Map 覆盖;最后,dependencyManagement 依赖锁定原则稍有些复杂,因为它涉及到了 dependencyManagement 的版本解析,并以解析出来的版本号为准。

在现实工作中,这几种依赖关系可能同时存在。尤其在大型工程中,dependencyManagement 版本锁定运用非常广泛,如果能从源码角度掌握其运行原理,一定会提升你对 Maven 的运用能力。

资源

本文中用到的源码已上传至 Github,地址:https://github.com/xiaoxi666/mavenDependencyDemo,需要的小伙伴请自行下载。

在阅读源码的过程中,我们学到了什么?

首先,我们了解了 Maven 依赖调解实现原理,以后面对各种输出信息,能够做到心中有数。稍微拓展一下,各种依赖管理工具的核心原理其实都差不多,无非就是管理各种依赖版本。希望本文能为你理解包管理工具的实现思路提供些许参考。

其次是设计方面的考量。Maven 提供了核心实现,并且预留了各种扩展点,可以让不同的插件实现不同的功能。这种开发模式可以非常方便功能扩展,对于一款软件的成长是很有利的。业界也有很多采用这种思路开发的产品,比如你熟悉的 Atom。

再说说算法,其实就是很经典的递归算法,以及常提到的备忘录(Map 存储已经解析过的依赖)。

最后,谈谈设计模式的体现。上面提到的源码就有几种,比如模板模式(不同冲突调解器的实现)、访问者模式(参照 visit 方法)、观察者模式(各种 Listener,事件产生时打印一些信息),以及桥接模式(dependency:tree 的实现其实是一个桥,类似于 slf4j 的模式)等等。

当然,你还学会了一种简单方便的 Maven 源码调试方法,哈哈。

参考

《Maven 实战》

Maven 官网:https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html

Maven 依赖调解源码解析(七):总结的更多相关文章

  1. Maven 依赖调解源码解析(一):开篇

    本文是系列文章<Maven 源码解析:依赖调解是如何实现的?>第一篇,主要做个开头介绍.并为后续的实验做一些准备.系列文章总目录参见:https://www.cnblogs.com/xia ...

  2. Maven 依赖调解源码解析(二):如何调试 Maven 源码和插件源码

    本文是系列文章<Maven 源码解析:依赖调解是如何实现的?>第二篇,主要介绍如何调试 Maven 源码和插件源码.系列文章总目录参见:https://www.cnblogs.com/xi ...

  3. Maven 依赖调解源码解析(三):传递依赖,路径最近者优先

    本文是系列文章<Maven 源码解析:依赖调解是如何实现的?>第三篇,主要介绍依赖调解的第一条原则:传递依赖,路径最近者优先.本篇内容较多,也是开始源码分析的第一篇,请务必仔细阅读,否则后 ...

  4. Maven 依赖调解源码解析(四):传递依赖,第一声明者优先

    本文是系列文章<Maven 源码解析:依赖调解是如何实现的?>第四篇,主要介绍依赖调解的第二条原则:传递依赖,第一声明者优先.请按顺序阅读其他系列文章,系列文章总目录参见:https:// ...

  5. Maven 依赖调解源码解析(五):同一个文件内声明,后者覆盖前者

    本文是系列文章<Maven 源码解析:依赖调解是如何实现的?>第五篇,主要介绍同一个文件内声明,后者覆盖前者的原则.请按顺序阅读其他系列文章,系列文章总目录参见:https://www.c ...

  6. Maven 依赖调解源码解析(六):dependencyManagement 版本锁定

    本文是系列文章<Maven 源码解析:依赖调解是如何实现的?>第六篇,主要介绍 dependencyManagement 版本锁定原则.请按顺序阅读其他系列文章,系列文章总目录参见:htt ...

  7. QT源码解析(七)Qt创建窗体的过程,作者“ tingsking18 ”(真正的创建QPushButton是在show()方法中,show()方法又调用了setVisible方法)

    前言:分析Qt的代码也有一段时间了,以前在进行QT源码解析的时候总是使用ue,一个函数名在QTDIR/src目录下反复的查找,然后分析函数之间的调用关系,效率实在是太低了,最近总结出一个更简便的方法, ...

  8. Celery 源码解析七:Worker 之间的交互

    前面对于 Celery 的分布式处理已经做了一些介绍,例如第五章的 远程控制 和第六章的 Event机制,但是,我认为这些分布式都比较简单,并没有体现出多实例之间的协同作用,所以,今天就来点更加复杂的 ...

  9. jQuery 源码解析(七) jQuery对象和DOM对象的互相转换

    jQuery对象是一个类数组对象,它保存的是对应的DOM的引用,我们可以直接用[]获取某个索引内的DOM节点,也可以用get方法获取某个索引内的DOM节点,还可以用toArray()方法把jQuery ...

随机推荐

  1. github注册教程最新版(十年程序员保姆级教程)

    您可以在墨抒颖的网站体验本文章的纯净版 准备 拥有一个可以接受信息的邮箱即可 开始 点击github官网github step1.进入注册页面 点击Sign Up进入注册流程 step2.输入邮箱 这 ...

  2. Go语言核心36讲(Go语言基础知识一)--学习笔记

    01 | 工作区和GOPATH 从 Go 1.5 版本的自举(即用 Go 语言编写程序来实现 Go 语言自身),到 Go 1.7 版本的极速 GC(也称垃圾回收器),再到 2018 年 2 月发布的 ...

  3. 解决npm : 无法加载文件 D:\Code\renren-fast-vue\node_modules\.bin\npm.ps1,因为在......

    解决这个问题: 看看错误信息: npm : 无法加载文件 D:\DevPath\nodejs\npm.ps1,因为在此系统上禁止运行脚本.有关详细信息,请参阅 https:/go.microsoft. ...

  4. SignalR 在React/GO技术栈的生产应用

    哼哧哼哧半年,优化改进了一个运维开发web平台. 本文记录SignalR在react/golang 技术栈的生产小实践. 1. 背景 有个前后端分离的运维开发web平台, 后端会间隔5分钟同步一次数据 ...

  5. [no code][scrum meeting] Beta 5

    $( "#cnblogs_post_body" ).catalog() 例会时间:5月18日14:30,主持者:叶开辉 下次例会时间:5月19日11:30,主持者:黎正宇 一.工作 ...

  6. activiti流程图上获取各节点的信息获取

    背景:         由于项目的需要,当用户在查看流程图时,当点击某个流程图片上的节点时,需要提示一些信息,这就需要获取各个节点的信息,此处获取id和name的值.           注意:这个并 ...

  7. 关于麦克风的参数介绍 - 驻极体麦克风(ECM)和硅麦(MEMS)

    1.麦克风的分类1.1.动圈式麦克风(Dynamic Micphone)原理:基本构造包含线圈.振膜.永久磁铁三部分.当声波进入麦克风,振膜受到声波的压力而产生振动,与振膜在一起的线圈则开始在磁场中移 ...

  8. MIPI归纳---为什么阻抗为100欧姆

    根据LVDS(Low Voltage Differential Signaling)电平定义的. LVDS差分信号PN两线最大幅度是350mV,内部一个恒流源电流是3.5mA.于是终端匹配电阻是100 ...

  9. Spark面试题整理(三)

    1.为什么要进行序列化序列化? 可以减少数据的体积,减少存储空间,高效存储和传输数据,不好的是使用的时候要反序列化,非常消耗CPU. 2.Yarn中的container是由谁负责销毁的,在Hadoop ...

  10. 视频编码GOP

    GOP group of pictures GOP 指的就是两个I帧之间的间隔. 比较说GOP为120,如果是720 p60 的话,那就是2s一次I帧. 在视频编码序列中,主要有三种编码帧:I帧.P帧 ...