先说成果,maven 依赖申明中加了 <scope>provided</scope>
,或者加了 <optional>true</optional>
,从成果上看是一样的,都会中断依赖传递,察看下图:
图中,我的项目 B 别离依赖了 C 和 D,只不过一个申明了 optional=true,一个申明了 scope=provided,而后我的项目 A 再申明了 B 的依赖,此时在我的项目 A 环境中,既没有 C,也没有 D,所以在成果上看,它们是一样的。
那它们有哪些区别呢?
先看一下 maven 官网文档上对二者的形容:
-
optional:
If project Y depends on project Z, the owner of project Y can mark project Z as an optional dependency, using the “optional” element. When project X depends on project Y, X will depend only on Y and not on Y’s optional dependency Z. The owner of project X may then explicitly add a dependency on Z, at her option. (It may be helpful to think of optional dependencies as “excluded by default.”)
-
provided
This is much like compile, but indicates you expect the JDK or a container to provide the dependency at runtime. For example, when building a web application for the Java Enterprise Edition, you would set the dependency on the Servlet API and related Java EE APIs to scope provided because the web container provides those classes. A dependency with this scope is added to the classpath used for compilation and test, but not the runtime classpath. It is not transitive.
大略意思是说,在 A 我的项目依赖 B 我的项目提供了一些个性,但又不想让这些个性默认提供,而是作为能够抉择的附加性能,默认不提供,须要申明后(被动增加 B 我的项目的依赖)才失效,这时用 optional;而对于 provided,文档偏重提到了 运行环境
概念,强调只在编译时存在,而运行时不存在的依赖,也就是说,provided 的主要用途不是为了思考依赖是否传递,而是要看我的项目运行时是不是不应该有这个依赖(是不是须要 jvm 或者运行容器提供)。
常常拿 scope=provided 来举例的经典场景之一,就是 servlet-api
这个依赖了,在代码 coding 阶段须要应用到它的一些 api,而在理论运行时,它的作用要由具体的运行容器来实现,因而编译时能够有它,而打成 war 包放到 tomcat 环境下运行时,war 包外面不应该有这个servlet-api.jar
,否则就会报错了。
在理论的 spring-boot 我的项目中,因为大部分应用了内置的 undertow
或者 tomcat
容器,曾经不须要特地申明这个 jar 的 provided 属性了。事实上,日常中更常常须要被用到的,应该次要就是这个 optinal 了,比方你要提供一组根底 jar 包,供项目组中的其余共事在他们的我的项目中引入依赖应用时,如果你提供的某些依赖了其余 jar 包来做的性能并不一定会被应用到,便能够用到这个 optinal 了。特地是用到诸如 @ConditionalOnClass
这种检测我的项目中是否存在某个 class 的判断条件时,更是用 optional 的好时机。
而 provided
的应用场景,除了 servlet-api
,lombok
也很适宜:A 我的项目应用 lombok 做了一些代码生成,实现开发须要 deploy 到私服仓库之前,记得要将 lombok 的依赖加上<scope>provided</scope>
,因为它的作用周期曾经在 A 我的项目打包实现时完结了,对于依赖 A 我的项目的其余我的项目,不须要用到 lombok 这个玩意儿,它们须要的是 A 我的项目提供的性能,而不是附带的帮忙本人生成代码的额定性能;也不应该用optional
,因为没什么好抉择的,它并不是 A 我的项目提供的可选性能之一。
参考资料:Difference Between <optional>true</optional> and <scope>provided</scope> | by Furkan Danışmaz | Medium