必威体育Betway必威体育官网
当前位置:首页 > IT技术

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

时间:2019-08-09 11:12:26来源:IT技术作者:seo实验室小编阅读:57次「手机版」
 

provided

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

文章目录

    • 一 介绍
      • 1 scope设为provided
      • 2 optional设为true
      • 3 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

相关阅读

分享到:

栏目导航

推荐阅读

热门阅读