我什么时候需要与运行时范围的maven依赖

Tuo*_*nen 7 java dependencies jar maven

我试图了解runtimemaven中作用域依赖的特定需求.在哪种情况下我需要这个,哪个都没有compile,provided范围不会?

例如,compile当我必须直接在代码中调用库API(针对它进行编译)并将依赖项打包到工件或依赖项目工件中时,我会使用scope作为依赖项.

provided当我必须针对API进行编译时,我会使用范围,但不要打包它(除了它在运行时可用).

但我runtime什么时候需要范围?这是针对什么情况,当我不直接调用库API(而是使用反射),但是想要将它打包在工件中?为什么不只是使用compile范围?唯一的好处是编译时间更快,或者是否有其他特殊的runtime范围无法通过compile范围实现或避免?

dav*_*xxx 15

您可以runtime使用默认范围完成对范围执行的所有操作:compile.
为什么要使用runtime

因为在某些情况下,这非常有意义,可以使您的构建更加健壮.

典型的用例是确保客户端代码不使用特定的实现.

假设您构建一个依赖于打包为Maven依赖项(my-service-api)的API的应用程序,并将此API的实现打包为另一个Maven依赖项(my-service-impl).
假设您现在需要在构建的应用程序中的运行时提供实现,但您不希望应用程序的客户端代码直接引用实现.

通过使用runtime范围my-service-impl:

<dependencies>
?  <dependency>
?      <groupId>my-group</groupId>
?      <artifactId>my-service-api</artifactId>
?  </dependency>
?  
?  <dependency>
?      <groupId>my-group</groupId>
?      <artifactId>my-service-impl</artifactId>
?      <scope>runtime</scope>
?  </dependency>
<dependencies>
Run Code Online (Sandbox Code Playgroud)

由于编译器永远不会在类路径中具有依赖关系,因此无法在应用程序的客户端代码中创建与实现的任何耦合.
客户端代码只会看到依赖项的API:

通过使用compile范围my-service-impl:

<dependencies>
?  <dependency>
?      <groupId>my-group</groupId>
?      <artifactId>my-service-api</artifactId>
?  </dependency>
?  
?  <dependency>
?      <groupId>my-group</groupId>
?      <artifactId>my-service-impl</artifactId>    ?  
?  </dependency>
<dependencies>
Run Code Online (Sandbox Code Playgroud)

事情是不同的:你可能会错误地引用实现类,因此创建了与实现的不良耦合.

支持runtime范围的已知用法是您必须处理特定DBMS(Oracle,PostgreSQL或其他)的JDBC依赖关系.
要编写可移植代码,您不希望允许客户端代码引用此JDBC依赖项的类,但是您希望所有相同的内容都包含在应用程序中,因为在运行时需要使用类API来使JDBC API与此DBMS一起使用.


gly*_*ing 6

其范围存在相当大的混乱runtime。我认为这种混乱反映了它的边际效益以及缺乏真正令人信服的通用用例。

常见的好处是:

  • 它们有助于避免意外的依赖
  • 它们方便使用,并Class.forName("a.b.ClassName")允许您切换“abClassName”表示的绑定,而无需重新编译您的应用程序。此优势的常见示例:JDBC 驱动程序和 SLF4J 绑定

但是,考虑到普遍的混乱和边际收益,我建议坚持使用范围,除非您遇到了范围真正有用的compile极端情况之一。runtime


Tho*_*s.L 5

runtime 这个作用域表示编译时不需要依赖,但执行时需要依赖。它位于运行时和测试类路径中,但不在编译类路径中。

这意味着库中的类存在于 JVM 类路径(运行时环境)中,但不存在于 Java 编译器类路径(编译时)中,因此在编译项目时,这些类对编译器不可见。您不能在编译时使用/导入任何这些类。此范围对于动态加载的类(即您将在运行时引用/加载的类)很有用。