当工件构建为 JAR 时,maven 范围
compile
和 provided
之间有什么区别?如果是 WAR,我会理解 - 该工件将包含或不包含在 WEB-INF/lib 中。但对于 JAR 来说这并不重要——不包含依赖项。当它们的作用域为 compile
或 provided
时,它们必须位于类路径上。我知道 provided
依赖关系不可传递 - 但这只是一个区别吗?
编译意味着您需要JAR来编译和运行应用程序。对于Web应用程序,例如,JAR将放置在WEB-INF/lib目录中。
提供意味着您需要 JAR 来编译,但在运行时环境已经提供了 JAR,因此您不需要将其与应用程序一起打包。 对于 Web 应用程序,这意味着 JAR 文件 不会放入WEB-INF/lib目录下。
对于 Web 应用程序,如果应用程序服务器已经提供了 JAR(或其功能),则使用“provided”,否则使用“compile”。
来自 Maven 文档:
编译
这是默认范围,如果未指定则使用。编译 依赖项在项目的所有类路径中都可用。 此外,这些依赖项会传播到依赖项目。
提供
这很像编译,但表明您期望 JDK 或 容器在运行时提供依赖关系。例如,当 为 Java 企业版构建 Web 应用程序,您将 将 Servlet API 和相关 Java EE API 的依赖关系设置为 提供范围是因为 Web 容器提供了这些类。这 范围仅在编译和测试类路径上可用,并且是 不具有传递性。
回顾:
如果您计划生成一个包含其所有依赖项的 JAR 文件(典型的 xxxx-all.jar),那么提供的范围很重要,因为此范围内的类不会打包在生成的 JAR 中。
请参阅 maven-assemble-plugin 了解更多信息
- 编译
使可用到类路径中,如果是普通jar,则不要将此依赖项添加到最终jar中;但是如果最终的jar是单个jar(例如可执行jar),则将此jar添加到jar中
- 提供
依赖将在运行时环境中可用,因此无论如何都不要添加此依赖;即使不在单个 jar 中(即可执行 jar 等)
对于 jar 文件,如果在 maven-jar-plugin 配置中将 addClassPath 设置为 true,则差异在于 jar 中包含的 MANIFEST.MF 文件中列出的类路径。 “编译”依赖项将出现在清单中,“提供”依赖项则不会。
我最讨厌的事情之一是这两个词应该具有相同的时态。要么编译提供,要么编译提供。
如果 jar 文件类似于可执行的 spring boot jar 文件,那么所有依赖项的范围必须是
compile
以包含所有 jar 文件。
但是如果 jar 文件在其他包或应用程序中使用,则不需要在 jar 文件中包含所有依赖项,因为这些包或应用程序本身可以提供其他依赖项。
如果 JAR A 在编译时具有依赖项 B,则 B 将是 A 的传递依赖项。这意味着: