Maven 依赖 怎么办?

251 阅读2分钟

怎么认识 pom 依赖?

Maven 依赖唯一性:GAV

  • groupId: 公司 或 架构名称
  • artifactId: 项目名
  • version: 版本号

引用依赖的标签:

  • <dependencies>: 引入依赖的信息
  • <dependencyManagement>: 只声明但并不引入,主要用于管控 version
    • 实际引入依赖时可以缺省version
    • 间接依赖导致多版本时,声明最终引入的版本
  • <parent>: 声明 parent 依赖
    • 子类继承父 pom,有冲突则 子类优先
    • 分类继承:dependencies 继承 dependencies,dependencyManagement 继承 dependencyManagement
  • <properties>: 声明当前项目属性的集合,仅代表声明,不代表引用。常用于声明版本信息

依赖的作用域

  • compile: 打包,其他环节不生效。默认值可以不写
  • provided: 线上已经提供了这个 jar 包,打包时无需考虑
  • system: 和 provided 无太大差别
  • test: 只对测试代码生效,对应 scr/test
  • import: 只会在 dependencyManagement 中出现,解决 maven 依赖的单 parent 继承问题。import 后会把此 pom 的 dependencyManagement 注入到当前 pom, 但是不会引入当前依赖本身
  • runtime: 和 compile 类似,只对打包环节生效

怎么确定依赖的版本?

pom 结构

pom 文件的依赖关系是一个树,而非线性依赖。我们引入的依赖会有很多间接依赖,这些间接依赖很容易出现版本冲突,就需要额外的版本管理机制。

image.png

maven 仲裁机制

优先级:

  • 路径深度:越靠近根节点越优先
  • 深度一致:
    • 直接依赖: 靠后优先。后面的覆盖前面的
    • 间接依赖:靠前优先

示例如下,左图 D-5 长度短,该版本优先。右图 B1 属于直接依赖,靠前更优先;D2 属间接依赖,靠后更优先

image.png

覆盖机制:

  • dependencyManagement 中声明 pom 的优先级:
    • 使用靠前声明的版本
    • 只对不声明 version 的版本有效,声明 version 则以声明的版本为准
  • 覆盖原则: 子 pom 版本覆盖父 pom

下图中,最终生效版本为子 pom 的 1.2.25 image.png 下图中,最终生效版本为子 pom 使用的声明的版本 1.2.77

image.png

多 pom 的合并打包

多 pom 构建原则: 被依赖方在前,依赖方在后。不能出现循环依赖

打包标记:<build>

打包原则:构建顺序越靠后越优先,最不被依赖的 pom 会作为树的根,决定最终的依赖版本

如下图,距离 pom3 更近的 A2, B2, E2, F2, D1 会成为最终的打包产物

image.png

原文链接:阿里云-安全同学讲Maven间接依赖场景的仲裁机制