美文网首页
通过一些常见问题回顾Maven依赖中容易犯错的点

通过一些常见问题回顾Maven依赖中容易犯错的点

作者: 干货满满张哈希 | 来源:发表于2020-04-15 16:54 被阅读0次

    原文地址: http://andresalmiray.com/maven-dependencies-pop-quiz-results/

    网上看到这篇文章,感觉很有价值,弄清了一些我之前理解错的点,这里翻译并分享下.

    首先,先上一下我个人总结的结论

    Maven依赖可以分为如下几部分:

    1. 直接依赖,就是本项目 dependencies 部分的依赖
    2. 间接依赖,就是本项目 dependencies 部分的依赖所包含的依赖
    3. 依赖管理,就是本项目 dependency management 里面的依赖
    4. parent 的直接依赖
    5. parent 的间接依赖
    6. parent 的依赖管理
    7. bom 的直接依赖(一般没有)
    8. bom 的间接依赖(一般没有)
    9. bom 的依赖管理

    可以这么理解依赖:

    1. 首先,将 parent 的直接依赖,间接依赖,还有依赖管理,插入本项目,放入本项目的直接依赖,间接依赖还有依赖管理之前
    2. 对于直接依赖,如果有 version,那么就依次放入 DependencyMap 中。如果没有 version,则从依赖管理中查出来 version,之后放入 DependencyMap 中。key 为依赖的 groupId + artifactId,value为version,后放入的会把之前放入的相同 key 的 value 替换
    3. 对于每个依赖,各自按照 1,2 加载自己的 pom 文件,但是如果第一步中的本项目 dependency management 中有依赖的版本,使用本项目 dependency management的依赖版本,生成 TransitiveDependencyMap,这里面就包含了所有的间接依赖。
    4. 所有间接依赖的 TransitiveDependencyMap, **对于项目的 DependencyMap 里面没有的 key,依次放入项目的 DependencyMap **
    5. 如果 TransitiveDependencyMap 里面还有间接依赖,那么递归执行3, 4。

    由于是先放入本项目的 DependencyMap,再去递归 TransitiveDependencyMap,这就解释了 maven 依赖的最短路径原则。

    Bom 的效果基本和 Parent 一样,只是一般限制中,Bom 只有 dependencyManagement 没有 dependencies

    1. 简单项目依赖

    1. 下面这个 maven 依赖,我们有两个一样的依赖,但是不同的版本,最后项目会依赖哪个版本呢?

    image
    答案是 28.2-jre,相同依赖不同版本,以最后的为准,根据最开始依赖载入步骤的第二步,依赖会被替换。

    验证:


    image

    2. 下面这个 pom 文件中, Truth 1.0这个依赖里面有对于 guava 27.0.1-android 的依赖,那么最后 guava 是哪个版本?

    image

    这个可能是我们经常会遇到的情况,例如对 netty 的依赖,如果你的项目使用了 Spring Cloud,RocketMQ,Redisson等,就会发现其实他们各自的netty依赖都不太一样。项目会以最短路径原则为准,决定依赖的版本。这里就是 guava 28.2-jre

    验证:


    image

    3. 如果将 guava-27.0-jre 这个依赖放入 dependencyManagement 中,Truth 1.0这个依赖里面有对于 guava 27.0.1-android 的依赖,那么最后 guava 是哪个版本?

    image

    非显示依赖,一切以 dependencyManagement 中的版本为准,可以参考最开始提到的步骤中的第三步。所以这里是 guava-27.0-jre

    验证:


    image

    4. 下面这个项目中Truth 1.0这个依赖里面有对于 guava 27.0.1-android 的依赖,最后 guava 是哪个版本?

    image
    由于 dependencies 中有显式依赖,根据最开始我们提到的5步中可以看出,有显式依赖以这个依赖为准。所以答案是 guava-28.2-jre

    验证:


    image

    5. 下面这个项目中Truth 1.0这个依赖里面有对于 guava 27.0.1-android 的依赖,guice 4.2.2 中有对于 guava 25.1-android 的依赖,最后 guava 是哪个版本?

    image
    根据我之前总结的步骤,guice 和 Truth 会各自加载自己的依赖放入 TransitionDependencyMap,然后放入项目的 DependencyMap,已存在的 key 不会再次放入,所以谁先放入就是谁,这也是最短路径原则。这里就是 guice 的依赖优先,因为他在前面。答案是 guava-25.1-android
    image

    6. 下面这个项目中Truth 1.0这个依赖里面有对于 guava 27.0.1-android 的依赖,guice 4.2.2 中有对于 guava 25.1-android 的依赖,最后 guava 是哪个版本?

    image
    根据我之前总结的步骤,间接依赖版本优先根据项目的 dependencyManagement,所以这里版本是 guava-28.2-jre
    image

    2. 有 parent 的项目

    7. 下面这个项目中Truth 1.0这个依赖里面有对于 guava 27.0.1-android 的依赖,最后 guava 是哪个版本?

    image

    根据我之前总结的步骤,parent 的 dependencies 是直接加到本项目中,所以答案是 guava-28.2-jre

    验证:


    image

    8. 下面这个项目中Truth 1.0这个依赖里面有对于 guava 27.0.1-android 的依赖,最后 guava 是哪个版本?

    image
    根据我之前总结的步骤,parent 的 dependencies 还有 dependencyManagement 是直接加到本项目中,并且 dependencies 是最优先的,所以答案是 guava-28.2-jre

    验证:


    image

    9. 下面这个项目中Truth 1.0这个依赖里面有对于 guava 27.0.1-android 的依赖,最后 guava 是哪个版本?

    image

    根据我之前总结的步骤,parent 的 dependencyManagement 是直接加到本项目中,非显示依赖,一切以 dependencyManagement 中的版本为准,所以答案是guava-26.0-jre

    验证:


    image

    10. 下面这个项目中Truth 1.0这个依赖里面有对于 guava 27.0.1-android 的依赖,最后 guava 是哪个版本?

    image

    根据我之前总结的步骤,parent 的 dependencyManagement 是直接加到本项目中,并且在本项目的前面,dependencyManagement 也是一个map,后面的替换前面的,所以dependencyManagement中的版本是28.2-jre,非显示依赖,一切以 dependencyManagement 中的版本为准,所以答案是guava-28.2-jre

    验证:


    image

    3. 包含 bom 的项目

    11. 下面这个项目中Truth 1.0这个依赖里面有对于 guava 27.0.1-android 的依赖,guice 4.2.2 中有对于 guava 25.1-android 的依赖,最后 guava 是哪个版本?

    image

    根据我之前总结的步骤,bom 和 parent 一样,其中的 dependencyManagement 是直接加到本项目中,非显示依赖,一切以 dependencyManagement 中的版本为准,所以答案是guava-28.2-jre

    验证:


    image

    12. 下面这个项目中Truth 1.0这个依赖里面有对于 guava 27.0.1-android 的依赖,最后 guava 是哪个版本?

    image

    根据我之前总结的步骤,bom 和 parent 一样, 其中的 dependencyManagement 还有 dependencies 是直接加到本项目中,并且在本项目的前面,根据最短路径原则,答案是guava-28.2-jre

    但是注意 一般标准的 bom 只有 dependencyManagement, 没有dependencies

    验证:


    image

    13. 下面这个项目中Truth 1.0这个依赖里面有对于 guava 27.0.1-android 的依赖,最后 guava 是哪个版本?

    image

    根据我之前总结的步骤,bom 和 parent 一样, 其中的 dependencyManagement 是直接加到本项目中,并且在本项目的前面,,dependencyManagement 也是一个map,后面的替换前面的,所以dependencyManagement中的版本是28.2-jre,非显示依赖,一切以 dependencyManagement 中的版本为准,所以答案是guava-26.0-jre

    验证:


    image

    14. 下面这个项目中Truth 1.0这个依赖里面有对于 guava 27.0.1-android 的依赖,最后 guava 是哪个版本?

    image

    根据我之前总结的步骤,这个就很简单啦,最短路径原则,所以答案是guava-28.2-jre

    验证:


    image

    相关文章

      网友评论

          本文标题:通过一些常见问题回顾Maven依赖中容易犯错的点

          本文链接:https://www.haomeiwen.com/subject/rlthvhtx.html