背景
我们在maven中在处理项目模块的依赖的传递性时,我们经常使用optional标签或者设置scope为provided,使得依赖不向后传递。
- A为主项目
<dependency>
<groupId>com.xxx</groupId>
<artifactId>project-b</artifactId>
</dependency>
- B为模块
<dependency>
<groupId>com.xxx</groupId>
<artifactId>project-c</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.xxx</groupId>
<artifactId>project-d</artifactId>
<scope>provided</scope>
</dependency>
模块C和模块D,均不会传递至项目A中,两者有什么区别呢?
不同点
官方介绍[1][2]
-
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. -
optional
Optional dependencies are used when it’s not possible (for whatever reason) to split a project into sub-modules. The idea is that some of the dependencies are only used for certain features in the project and will not be needed if that feature isn’t used. Ideally, such a feature would be split into a sub-module that depends on the core functionality project. This new subproject would have only non-optional dependencies, since you’d need them all if you decided to use the subproject’s functionality.
However, since the project cannot be split up (again, for whatever reason), these dependencies are declared optional. If a user wants to use functionality related to an optional dependency, they have to redeclare that optional dependency in their own project. This is not the clearest way to handle this situation, but both optional dependencies and dependency exclusions are stop-gap solutions.
optional:表示功能可选,当项目中存在多个功能或者存在同一功能多种实现(使用时只选择一种实现),由使用方选择是否启用或者选择启动哪种实现,更多表示功能选择。如果不需要此功能,则不引入该包,打包更加节省空间。
provided:表示由JDK或者容器在运行态提供,依赖只在compile和test生效,不向后传递依赖。
两者更多在逻辑上的区别,optional告知依赖存在可选功能,由使用方选择是否引入启用,打包时更节省内存;provided告知依赖该功能由运行态提供(或只在编译态使用);两者都能起到依赖不向后传递的作用,当前理解只是语义的区别
引用
[1] https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
[2] https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html
[3] https://medium.com/@danismaz.furkan/difference-between-optional-true-optional-and-scope-provided-scope-7404ec24fb59