scope属性主要用于控制依赖范围,主要分为编译、打包、运行、测试、依赖传递等各个常见,scope不同于optional提供了更多可选择的配置参数用于应对不同的依赖场景。
scope 属性一般配置在依赖节点内。
该属性的主要作用是用于控制当前依赖的依赖范围。
简单来说就是控制依赖在应用的编译到发布过程中生效的范围。
比如下方样式就是大名鼎鼎的 lombok 插件,配置为 provided(已提供范围)。
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok do not compile-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.14</version>
<!-- compile:默认范围,用于编译 -->
<!-- provided:类似于编译,但支持你期待jdk或者容器提供,类似于classpath -->
<!-- runtime:在执行时需要使用 -->
<!-- test:用于test任务时使用 -->
<!-- system:需要外在提供相应的元素。通过systemPath来取得 -->
<!-- systemPath:仅用于范围为system。提供相应的路径 -->
<scope>provided</scope>
</dependency>
compile 是默认的范围。
一般来说如果 dependency 节点内没有配置 scope,就表示是 compile。
编译范围依赖在所有的 classpath 中可用,打包时该依赖会被打包。
该依赖会被传递。
provided 依赖表示该依赖在实际 JDK 或容器中已存在。
已提供范围的依赖在编译 classpath 可用。
打包时该依赖不会被打包。
常见的例子:
Web 应用在编译时需要依赖的 ServletAPI 来编译 servlet,但实际打包时并不需要这个 ServletAPI。
因为 ServletAPI 的 jar 包往往由应用服务器或者 servlet 容器(如 Tomcat)提供。
因此可以将 ServletAPI 依赖配置为 provided。
同理本文上方例子里的 lombok 插件也只是编译的时候需要。
该依赖不会被传递。
runtime 依赖在运行和测试系统的时候需要,但在编译的时候不需要。
runtime 与 provided 刚好相反,打包时该依赖会被打包。
常见的例子:
编译的时候只需要 JDBC 的 API。
而在运行的时候才需要 JDBC 驱动。
该依赖会被传递。
test 范围依赖,在一般的编译和运行时都不需要,它们只有在测试编译和测试运行阶段可用。
该依赖不会被传递。
system 范围依赖与 provided 类似,但是你必须显式的提供一个对于本地系统中 JAR 文件的路径。
这么做是为了允许基于本地对象编译,而这些对象是系统类库的一部分。
这样的构件应该是一直可用的,Maven 也不会在仓库中去寻找它。
如果你将一个依赖范围设置成系统范围,你必须同时提供一个 systemPath 元素。
注意该范围是不推荐使用的(你应该一直尽量去从公共或定制的 Maven 仓库中引用依赖)。
system 一般用在某些特殊的 jar 包依赖(比如私有 jar 或者某些过期版本的 jar)
该依赖不会被传递。
<dependency>
<groupId>quartz</groupId>
<artifactId>quartz</artifactId>
<version>1.8.6</version>
<!-- system:需要外在提供相应的元素。通过systemPath来取得 -->
<scope>system</scope>
<!-- systemPath:仅用于范围为system。提供相应的路径 -->
<systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/quartz-1.8.6.jar</systemPath>
</dependency>
除了 scope 管理依赖范围之外,还有一个 optional 也用于控制依赖范围。
optional(可选的依赖)
理解为此功能/此依赖可选,如果不需要某项功能,可以不引用这个包。
optional 主要作用于其他依赖当前项目的工程,阻断依赖的传递。
简单来说:
A 配置了某个依赖(例如是下方的 devtools),设置 optional 为 true。
B 为 A 的子项目或依赖 A,这时候如需要 devtools,B 可以配置 devtools 的依赖。
如果 B 不需要 devtools,pom 文件无需任何配置(B 项目中不会自定引入 devtools)。
反之,如果 A 项目 optiona 设为 false 或没有设置(optiona 默认为 false)。
B 项目无论是否配置 devtools 该依赖都会被引入。
<!--devtools 热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
温馨提示:系统将通过浏览器临时记忆您曾经填写的个人信息且支持修改,评论提交后仅自己可见,内容需要经过审核后方可全面展示。