Maven范围编译与JAR包装之间的区别

也许这个问题似乎是一个陈词滥调,但它以某种方式困扰我。 在使用maven作用域compile provided什么区别,以及在artifact被构build为JAR时provided了什么? 如果它是WAR,那么我明白 – 工件将被包含或不包含在WEB-INF / lib中。 但是在JAR的情况下它并不重要 – 依赖不包括在内。 当它们的范围被compileprovided时,它们必须在classpath上。 我知道provided依赖不是传递的 – 但它只是一个区别?

从Maven Doc :

这是默认范围,如果没有指定,则使用该范围。 编译依赖关系在项目的所有类path中都可用。 而且,这些依赖关系被传播到依赖项目。

  • 提供

这非常类似于编译,但是表示您希望JDK或容器在运行时提供依赖关系。 例如,在为Java Enterprise Edition构buildWeb应用程序时,可以将Servlet API和相关Java EE API的依赖性设置为提供的范围,因为Web容器提供了这些类。 此作用域仅在编译和testing类path中可用,不可传递。

回顾:

  • 依赖不是传递的(正如你所提到的)
  • 提供的范围仅适用于编译和testing类path,而编译范围适用于所有类path。
  • 提供的依赖关系不打包

编译意味着您需要JAR来编译和运行应用程序。 例如,对于Web应用程序,JAR将被放置在WEB-INF / lib目录中。

这意味着您需要JAR进行编译,但是在运行时已经有了一个由环境提供的JAR,所以您不需要将它与您的应用程序打包在一起。 对于Web应用程序,这意味着JAR文件将不会被放置在WEB-INF / lib目录中。

对于Web应用程序,如果应用程序服务器已经提供了JAR(或其function),那么使用“provided”,否则使用“compile”。

这里是参考。

这里是关于所有支持的依赖关系的简介(源代码maven doc )

这是默认范围,如果没有指定,则使用该范围。 编译依赖关系在项目的所有类path中都可用。 而且,这些依赖关系被传播到依赖项目。

提供

这非常类似于编译,但是表示您希望JDK或容器在运行时提供依赖关系。 例如,在为Java Enterprise Edition构buildWeb应用程序时,可以将Servlet API和相关Java EE API的依赖性设置为提供的范围,因为Web容器提供了这些类。 此作用域仅在编译和testing类path中可用,不可传递。

运行

这个范围表示依赖不是编译所必需的,而是为了执行。 它在运行时和testing类path中,而不是在编译类path中。

testing

此范围表示依赖项对于应用程序的正常使用不是必需的,仅适用于testing编译和执行阶段。 这个范围不是传递的。

系统

这个范围与提供的范围相似,除了必须明确提供包含它的JAR。 工件始终可用,不会在存储库中查找。

导入(仅在Maven 2.0.9或更高版本中可用)

这个范围只支持types为pom的依赖。 它指示依赖项将被replace为指定POM的依赖项的有效列表。 由于它们被replace,因此具有导入范围的依赖关系实际上并不参与限制依赖关系的传递性。

如果您打算生成一个具有所有依赖关系的JAR文件(典型的xxxx-all.jar),那么提供的范围就很重要,因为这个范围内的类将不会被打包到JAR中。

有关更多信息,请参阅maven-assembly-plugin

如果是正常的jar文件,请将其放入类path中,不要将此依赖项添加到最终的jar文件中; 但如果最终的jar是一个单独的jar(例如,可执行的jar),将这个jar添加到jar中,

  • 提供

依赖将在运行时环境中可用,所以在任何情况下都不要添加这个依赖; 即使不是在单个jar(即可执行的jar等)

对于jar文件,如果在maven-jar-pluginconfiguration中将addClassPath设置为true,那么差别在于包含在jar中的MANIFEST.MF文件中列出的类path中。 '编译'依赖将出现在清单中,'提供'依赖不会。

我的宠儿之一就是这两个词应该有同样的时态。 要么编译提供,要么编译提供。