maven中强大的scope标签详解

maven中强大的scope标签详解

本文目的

  接上一篇maven的版本号version的总结及理解
  当我在封装工具jar包的时候,发现有些依赖,是一定要在工具代码里使用的,比如我做的工具包里使用了spring的方法,那我在工具项目里就需要引用spring-web包。
  但是因为咱们都是spring项目,像这个包肯定将来会在子项目里,比如通过引用了spring-boot-starter-web,自动将spring-web包也带进去了。那这样就会产生了引用冲突。如下图:
在这里插入图片描述
   一般这种情况,也不会出什么问题,基本开发工具、编译器,自动会优先引用其中一个。(依赖调解机制,后边会写到这个)
   但是作为一个合格的码农,这种事情尽管问题不大,但是凌乱的引用,违背我严谨的初衷。因此本篇的主角scope就是帮助我们解决这种问题的最佳方法。

正文

1. 什么是scope

   比如下图,看下scope的位置:

<dependency>
   <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.19</version>
    <scope>runtime</scope>
</dependency>
2. scope的概念

  首先,我们一个maven项目依赖生效其实分为三个时期,编译期测试期运行期,即,在编译代码的时候,需要使用一套classpath;test测试的时候使用另一套依赖classpath;而到了项目运行时,又需要另一套依赖classpath

  scope一般称为依赖范围。通过合理的配置,可以控制当前依赖在不同时期编译期测试期运行期生效的关系。

3. scope的分类

   scopecompiletestprovidedruntimesystemimport几种。

  • compile : 称为编译依赖范围。如果引用的依赖没有指定scope,默认会使用该依赖范围。使用此依赖范围,表示对于上边说的编译期测试期运行期三种classpath都有效。
  • test:称为测试依赖范围。只对测试期classpath有效,典型的是JUnit依赖,只需要在编译测试代码(src/test)和运行测试的时候才需要。
  • provided : 已提供依赖范围。对于编译期测试期classpath有效。使用该依赖范围,表示当前依赖将来会默认由引用项目一定引用,就不需要多引用了。本文最开始介绍的那种情况,就可以对工具项目中的spring-web依赖,加上<scope>provided</scope>标签。
  • runtime : 运行时依赖范围。对于测试期运行期classpath有效。
  • system : 系统依赖范围。该依赖和provided依赖范围一样,但是在使用该依赖的时候,需要指定systemPath标签,显示的指定依赖jar的路径。使用此依赖范围,表示的是从本地磁盘上找依赖,不是从maven仓库中解析了。使用此依赖的时候要注意,因为是从自己本地磁盘上找依赖,因此如果多个人在共同开发,比较麻烦,还要拷贝那个依赖jar到对方机器上的相同路径下。因此不建议使用这个依赖范围。
  • import : 导入依赖范围。该依赖对于上边说的三种classpath期都没有作用。该范围的依赖只在dependencyManagement标签才有效。它的作用是将目标pomdependencyManagement标签中的依赖,合并到当前pomdependencyManagement标签内,供引用项目中使用。由于import依赖的特殊性,一般看到import范围时,就会存在<type>pom</type>,即指向打包类型为pom的模块。比如下边这样:
<dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>1.5.4.RELEASE</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
</dependencyManagement>
4. 传递性依赖

  当一个项目引用了mybatis-plus-boot-starter包时,因为它的pom里配置了mybatis-plus依赖,并且声明了compile作用域,因此我引入前者后,同样也会把后者引入到项目中,如下图,这种叫传递性依赖。我通过idea看的项目依赖情况:
在这里插入图片描述
  另外,关于mybatis-plus-boot-starterpom,对于mybatis-plus的依赖情况如下:
在这里插入图片描述
  即声明了compile,因此对于mybatis-plus-boot-starter来说,因为mybatis-plus声明了compile,因此表示它在mybatis-plus-boot-starter中的编译期测试期运行期三种classpath都有效,而我们项目在引用mybatis-plus-boot-starter时,同样使用的是compile。这样就会让我们项目同时拥有了mybatis-plus
   如果我们修改不同的<scope>值,会看到不同的依赖效果,具体的效果参照《maven实战》里的下图:
在这里插入图片描述
   因此,依赖范围scope,不仅控制依赖于三种classpath的关系,还对依赖性传递产生影响。

5. scope的应用场景

  说了这么多的scope范围,一般的开发可能根本不关心,但是如果想更加严谨些,你就需要考虑这些,来保证项目的依赖管理更加规范。
   因为每个公司都有架构师,架构师负责对基础框架的升级改造,而他做的东西,将来都要封装成几个依赖Jar包,放到公司私服,将来供引用项目,直接使用。
   比如约定项目采用springboot + mybatis-plus + lombok + shiro + druid,这些不同的版本,都不应该让各个项目自己来引用,都应该架构师来约定好版本,把基础配置做成几个Jar,将这些相关依赖设置成<scope>compile</scope>(不写默认是compile),这样各个子项目都不需要单独引用这些依赖。
   而对于一些个别包,比如引用项目将来会一定引用的,这样做的依赖jar包,就可以设置成<scope>provided</scope>,比如像最开始说的那个spring-web包。

   下一篇 maven项目的结构为什么是这样的

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

茁壮成长的凌大大

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值