Maven 依赖的 Scope 元素

原文(简单修改):Maven 依赖中的 Scope 详解

scope 元素的作用:控制 dependency 元素的使用范围。通俗的讲,就是控制 jar 包在哪些范围被加载和使用。

compile(默认)

compile 是默认值,如果没有指定 scope 值,该依赖的 scope 为 compile。被依赖项目需要参与到当前项目的编译,测试,打包,运行等阶段。打包的时候通常会包含被依赖项目。

provided

被依赖项目理论上可以参与编译、测试、运行等阶段,相当于 compile,但是再打包阶段做了 exclude 的动作。

适用场景:例如,如果我们在开发一个 web 应用,在编译时我们需要依赖 servlet-api.jar,但是在运行时我们不需要该 jar 包,因为这个 jar 包已由应用服务器提供,此时我们需要使用 provided 进行范围修饰。再比如,Lombok 的作用是在编译阶段处理编译结果,而在正式编译完成之后,是不需要 Lombok 的,所以 Lombok 的 scope 为 provided。

runtime

表示被依赖项目无需参与项目的编译,但是会参与到项目的测试和运行。与 compile 相比,被依赖项目无需参与项目的编译。

适用场景:例如,在编译的时候我们只需要 JDBC API 的 jar 包,而在运行的时候我们才需要 JDBC 驱动包,所以 MySQL 等数据库供应商提供的驱动包的 scope 为 provided。

test

表示被依赖项目仅仅参与测试相关的工作,包括测试代码的编译,执行。

适用场景:例如,Junit 测试。

system

system 元素与 provided 元素类似,但是被依赖项不会从 maven 仓库中查找,而是从本地系统中获取,systemPath 元素用于制定本地系统中 jar 文件的路径。例如:

<dependency>
<groupId>org.open</groupId>
<artifactId>open-core</artifactId>
<version>1.5</version>
<scope>system</scope>
<systemPath>${basedir}/WebContent/WEB-INF/lib/open-core.jar</systemPath>
</dependency>

import

它只使用在<dependencyManagement>中,表示从其它的 pom 中导入 dependency 的配置。

在 SpringBoot 项目中,常会看到如下 pom 内容:

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

其中spring-boot-dependencies是用来做依赖版本管理的。这里 import scope 的作用是,把spring-boot-dependencies中的内容导入到dependencyManagement中。实际上我们可以自己在dependencyManagement中做依赖版本管理:

<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>

但是spring-boot-dependencies已经把 SpringBoot 相关的许多依赖版本管理好了,所以,我们直接导入即可。

scope 的依赖传递

A–>B–>C。当前项目为 A,A 依赖于 B,B 依赖于 C。知道 B 在 A 项目中的 scope,那么怎么知道 C 在 A 中的 scope 呢?答案是:

当 C 是 test 或者 provided 时,C 直接被丢弃,A 不依赖 C;否则 A 依赖 C,C 的 scope 继承于 B 的 scope。

  • testprovided的处理

    • test:C 只在测试阶段可用,A 在其运行时不需要 C,因此 C 被丢弃。
    • provided:C 由外部环境提供(例如,容器或应用服务器),A 也不需要 C,因此 C 被丢弃。
  • 范围继承

    • 当 C 的范围是compileruntime时,A 依赖于 C,并且 C 的范围会继承 B 的范围。这意味着:

      • 如果 B 的范围是compile,则 C 的范围也是compile
      • 如果 B 的范围是runtime,则 C 的范围也是runtime
      • 如果 B 的范围是test,则 C 的范围是test
posted @   Higurashi-kagome  阅读(27)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示