maven <dependency>中的<scope>:compile、provided、runtime

介绍

在pom.xml中,<dependency>内有<scope>标签,管理依赖的部署。

有6个值:

scope取值 有效范围(compile, runtime, test) 依赖传递 例子
compile all 是 spring-core
provided compile, test 否 servlet-api
runtime runtime, test 是 JDBC驱动
test test 否 JUnit
system compile, test 是
import

compile (编译范围)

默认范围,表示该依赖 在 编译,测试,运行 时都会用到,会被打包

provided (已提供范围)

范围是 provided 的依赖,打包时不包含该依赖,需要JDK、容器提供这个依赖。

如:servlet.jar,tomcat 已经包含该 jar,打包时就不需要包含该依赖了

例子

web 工程,添加 servlet-api.jar 依赖,如下:

<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>servlet-api</artifactId>
  <version>2.5</version>
</dependency>

启动会报错,因为 tomcat 也提供了 servlet-api.jar 包,与这个依赖中的 jar包冲突了

解决:

添加 <scope>provided</scope>,就不会冲突了,完整依赖如下:

<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>servlet-api</artifactId>
  <version>2.5</version>
  <scope>provided</scope>
</dependency>

在项目生成 war 包时,不会包含该 servlet-api.jar

runtime (运行时范围)

runtime 依赖在 运行 和 测试 的时候需要,在 编译 时不用

只在运行时使用,如JDBC驱动(用发射 Class.forName() 加载的驱动,编译时不需要,运行时才需要),适用运行和测试阶段。

例子

比如:jdbc驱动包,用反射 Class.forName() 加载的驱动,编译时不需要,运行时才需要

springboot热部署:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
</dependency>

关于热部署详细见:
https://www.malaoshi.top/show_1EF6Zz3koJq.html

system

类似provided,和 provided 的区别是,使用 system 范围的依赖时,一般是通过手动方式将 jar 安装到本地仓库中(必须通过 systemPath元素显式地指定依赖文件的路径),不是通过Maven仓库解析的,由于与本机系统绑定,可能造成构建的不可移植,因此应该谨慎使用

import

解决单继承问题,只能用在 dependencyManagement 里面

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。

感谢:
https://www.cnblogs.com/hzzll/p/6738955.html
https://www.cnblogs.com/huahua035/p/7680607.html
https://www.cnblogs.com/satire/p/15068971.html


原文出处:/show_1EF25Yk6oX28.html