Skip to content

Maven 中optional和scope的作用

1. optional

optional 是 Maven 依赖 jar 时的一个选项,表示该依赖是否可选的,项目之间依赖是否传递。不设置 optional(默认)或者 optional 是 false,表示传递依赖。

这里假设有两个项目 A 和 B,其中 A 为父项目,B 为子项目。在父项目中引入了单元测试 junit 的依赖;当父项目添加 junit 依赖时,并未添加 optional 选项,也就是默认的 optional 元素的值为 false,那么便具有依赖传递性,此时,子项目 B 中会直接引入父项目 A 中引入的 Junit 的 jar 包。也就是说 B 项目打包时,jar/war 包中会包含 junit 的 jar 包。

当父项目引入 junit 依赖时,设置 optional 元素为 true。那么,如果项目 B 不需要 Junit 的 jar 包,那么在其 pom文 件中不需进行任何处理便可以;如果 B 项目也需要对应的 jar 包依赖,可以有两种选择:第一、A 项目中对应依赖的 optional 设置为 false 或去掉;第二、B 项目中直接引入需要的该依赖。

2. scope

scope 元素主要用来控制依赖的使用范围,指定当前包的依赖范围和依赖的传递性,也就是哪些依赖在哪些 classpath 中可用。常见的可选值有:compile、provided、runtime、test、system 等。

compile(编译)

默认值。compile 表示对应依赖会参与当前项目的编译、测试、运行等,是一个比较强的依赖。打包时通常会包含该依赖,部署时会打包到 lib 目录下。

test(测试)

scope 为 test 表示依赖项目仅参与测试环节,在编译、运行、打包时不会使用。

runntime(运行时)

runntime 仅仅适用于运行和测试环节,在编译环境下不会被使用。比如编译时只需要 JDBC API 的 jar,而只有运行时才需要 JDBC 驱动实现。

provided(已提供) provided 适合在编译和测试的环境,和 compile 功能相似,但 provide 仅在编译和测试阶段生效,provide 不会被打包,也不具有传递性。比如:spring-boot-devtools、servlet-api 等,前者是因为不需要在生产中热部署,后者是因为容器已经提供,不需要重复引入。

system

system 范围依赖与 provided 类似,不过依赖项不会从 maven 仓库获取,而需要从本地文件系统提供。使用时,一定要配合 systemPath 属性。不推荐使用,尽量从 Maven 库中引用依赖。

2.1 scope 的传递性