依赖排除 provided,optional 和 exclusion 最全区分指南

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/alinyua/article/details/83785891

本文将介绍 Maven工程中3种避免依赖冲突的手段 provided,optional 和 exclusion 及其使用场景,并对其进行比较区分,最后以一个应用实例来做归纳总结。本人在网上寻找相关说明时大多语焉不详,模棱两可,有些甚至自己也没弄明白,故根据官方说明和自身试验写下此文,如有纰漏,还望指教。转载需经本人同意,注明出处方可转载。

一 介绍

为了方便叙述,以 项目B 为主体来讨论依赖与被依赖关系。
不管是provided,exclusion还是optional,都符合关系如下(虚线表示弱依赖)
下图表示在项目A没有直接依赖项目C的情况下,项目A都无法直接使用项目C,而项目B可以。

依赖于
无法获取
项目A
项目B
项目C

1 scope设为provided

  • 核心
    对象是依赖整体,依赖将提供编译而不参与打包,以使用方提供的为准,从而避免版本冲突
  • 使用场景
    希望协调依赖版本以使用方提供的为准
  • 典型应用
    项目B是我们要发布的组件,依赖于spring-boot 的部分功能(项目C),项目A要使用我们的组件,且项目A本身也是spring-boot项目,此时,对spring-boot的依赖极易出现版本冲突(项目A依赖的spring-boot版本可能经常变化)。此时就应以项目A的依赖为准,同时使得项目B也可以获得项目C升级的好处。如果不希望项目B依赖的项目C版本改变,则不应该用这种方式。
  • 使用方法
    项目B指定项目C的 dependency 下的 scope 为 provided
  • 图例
    如下,项目B原本依赖项目C1,但在项目A中引入了依赖项目C2(C1的另一版本)后项目A、B都使用项目C2
    需要注意的是,如果项目A中没有直接依赖项目C的话,项目B仍可以使用项目C1的功能,但项目A不可以,此时项目A中会提示项目C找不到。
依赖于
依赖于
依赖于
项目A
项目B
项目C1
项目C2

2 optional设为true

  • 核心
    避免传递传出
  • 使用场景
    希望隔绝依赖传递关系
  • 使用方法
    项目B指定项目C dependency 下的 optional为 true
  • 图例
    如下,项目A引入依赖项目C2后,项目A和项目B互不影响。(此时classpath下只有项目C2没有项目C1)
依赖于
依赖于
项目A
项目B
项目C1
项目C2

3 exclusion排除特定组件

相当于另一种形式的 optional 为 true

  • 核心
    避免传递导入
  • 使用场景
    希望隔绝依赖传递关系
  • 使用方法
    项目A指定项目B dependency 下的 exclusions->exclusion为要排除的项目C
  • 图例
    如下,项目A引入依赖项目C2后,项目A和项目B互不影响。(此时classpath下只有项目C2没有项目C1)
依赖于
依赖于
项目A
项目B
项目C1
项目C2

二 比较区别

相同点

  1. 不管哪种方法项目A都无法直接使用项目C,除非项目A直接引入项目C
  2. 不管哪种方法项目B都可以直接使用项目C,即使项目A没有直接引入

不同点

  1. scope设置为provided 是希望使用 classpath 提供的依赖,而另外两者则完全隔绝依赖关系
  2. exclusion和optional的区别在于 optional 是项目自身将依赖排除,不影响引用方使用。exclusion是引用方主动排除依赖

三 实例探究

现假设有:项目B需要使用Lombok的功能,但项目A不需要,但是项目A执行项目B的方法时必然会使用到Lombok的功能。
如下

依赖于
依赖于
项目A
项目B
Lombok模块
  1. 这个时候如果项目B中将Lombok模块的scope设为provided,和后两种方法效果相同,但Lombok作为工具类在满足当前工程的情况下并不需要变化(变化可能带来兼容性问题),如项目A如引入差异较大的Lombok版本,则可能使项目B无法正常使用。
  2. 如果项目B的optional设置为true则可以解决这个问题(这也是Lombok的推荐使用方法),项目A不需要再另外依赖Lombok也可以正确执行项目B的方法。如果项目A需要使用不同版本的Lombok也可以自行导入而不用担心版本冲突。
  3. 但是,如果项目B不是自己写的,而且其Lombok模块的optional为false(默认值),那我们就只能提供在项目A引入项目B的时候使用exclusion指定排除Lombok模块,达到和optional相同的效果。

参考

官方说明(exclusion和optional):http://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html

猜你喜欢

转载自blog.csdn.net/alinyua/article/details/83785891
今日推荐