当前位置: 首页 > 知识库问答 >
问题:

为什么Spring Boot starter依赖项的设计与Maven的可传递依赖机制的意图相反?

柴星津
2023-03-14

根据Maven依赖关系文档,所有编译依赖关系都要显式列出,而不是在编译时传递使用:

打算将[传递性编译依赖项]改为运行时范围,因此必须显式列出所有编译依赖项-但是,在某种情况下,您所依赖的库从另一个库扩展了一个类,迫使您在编译时可用。出于这个原因,编译时依赖项即使是传递的,也仍然作为编译范围。

Spring Boot有一个“启动器”依赖的概念。从Spring Boot自己的文档(以及我在Spring Boot自己的示例和其他地方看到的许多使用示例)可以清楚地看出,这些文档旨在通过传递方式引入许多其他依赖项,以便在运行时和编译时使用。根据Spring Boot的文档:

启动器是一组方便的依赖关系描述符,可以包含在应用程序中。您可以一站式地获得所需的所有Spring和相关技术,而无需搜索示例代码和复制粘贴负载的依赖描述符。例如,如果您想开始使用Spring和JPA进行数据库访问,只需在项目中包含Spring boot starter数据JPA依赖项,就可以了。

启动器包含许多使项目快速启动和运行所需的依赖项,并具有一组一致的、受支持的托管传递依赖项。

使用此机制以传递方式引入编译范围的依赖项似乎与Maven官方打算如何使用它们的意图不一致。其中一个非常清楚的地方是Maven依赖关系:分析插件目标,当直接使用Maven starter依赖关系时,它会显示警告。例如,在Spring Boot自己的“入门”示例中运行mvn dependency:analyze会生成以下输出:

[WARNING] Used undeclared dependencies found:
[WARNING]    org.springframework:spring-web:jar:4.3.6.RELEASE:compile
[WARNING]    org.springframework.boot:spring-boot-test:jar:1.5.1.RELEASE:test
[WARNING]    org.springframework.boot:spring-boot-test-autoconfigure:jar:1.5.1.RELEASE:test
[WARNING]    org.springframework:spring-test:jar:4.3.6.RELEASE:test
[WARNING]    org.springframework.boot:spring-boot:jar:1.5.1.RELEASE:compile
[WARNING]    org.hamcrest:hamcrest-library:jar:1.3:test
[WARNING]    org.springframework:spring-context:jar:4.3.6.RELEASE:compile
[WARNING]    junit:junit:jar:4.12:test
[WARNING]    org.springframework.boot:spring-boot-autoconfigure:jar:1.5.1.RELEASE:compile
[WARNING]    org.springframework:spring-beans:jar:4.3.6.RELEASE:compile
[WARNING] Unused declared dependencies found:
[WARNING]    org.springframework.boot:spring-boot-starter-web:jar:1.5.1.RELEASE:compile
[WARNING]    org.springframework.boot:spring-boot-starter-test:jar:1.5.1.RELEASE:test
[WARNING]    org.springframework.boot:spring-boot-starter-actuator:jar:1.5.1.RELEASE:compile

我的问题是,为什么Spring Boot starter模式的设计方式与底层构建系统的既定意图直接相反。是否有关于该主题的讨论或解释?

共有2个答案

杜志
2023-03-14

此问题在Spring Boot项目中作为Spring Boot#8341提出。一些Spring Boot开发人员回应了这个问题,表示他们认为这实际上并不是对Maven依赖机制的滥用。

备注:

为什么Spring Boot启动模式的设计方式与底层构建系统的意图直接相反?

在我看来,你在Maven的文档中一句话读得太多了。我认为这说明,即使被警告,你也必须选择加入。

有没有理由认为这种滥用是“可以的”?

滥用相当主观。我不认为首发是一种误用。如果您这样做了,那么您可以自由地显式声明所有编译依赖项。

是否有一种“正确”的方式可以更好地实现此功能——通过一个简单的Maven配置在已知版本集中方便地提供一组依赖项?

我不这么认为,这可能是为什么可传递的编译依赖项保留在编译范围内并且默认情况下不会生成警告的一个很好的原因。

备注:

您对这一点理解过度,而且您的观点在IMO中缺乏实用性。dependency:analyze的目标是为用户提供一种方法来检测您的编译类路径是否只包含您实际需要的内容。文档中的这句话仅仅是为了解释为什么编译范围也是可传递的。

[...]

回顾一下,您遇到的是一个Maven问题,而不是Spring Boot问题,因为大量没有使用Spring Boot的项目本身并没有列出所有的编译依赖项。

基于此反馈,已为Maven依赖插件创建了票证MDEP-557,以不对这些传递依赖使用发出警告。

因此,为了回答这个问题,Spring Boot团队认为这是对可传递依赖关系的适当使用,而且这并不违背Maven的意图。

林曦之
2023-03-14

看起来您已将依赖插件配置为在警告时失败。我认为如果您没有明确声明传递依赖项,依赖插件会发出警告。

尝试更改<代码>

 类似资料:
  • 这个问题将澄清什么是传递依赖,以及它在Maven中如何在非常高的级别上工作。 我的定义是:在依赖树中,比如-- 若C在B中有范围编译,那个么将B声明为A的依赖项就足以用Maven构建A。但是,如果C在B中提供了作用域,那么当Maven构建A时,除非A在其依赖项中声明C,否则该构建不会根据C自动编译A。 这是正确的吗?

  • 我的情况: 我有两个独立的项目A和B。 没有项目A。 A和B使用相同的库: < li >反射-0.9.9-RC1.jar < li >番石榴-11.0.2.jar < Li > XML-API-1.0 . B2 . jar < li>javassist-3.16.1-GA.jar < li>dom4j-1.6.1.jar < li>jsr305-1.3.9.jar 我制作了项目C,这是项目a的插件

  • 我是maven的新手。(我已经搜索了几个小时的答案,但没有运气。mvn依赖:复制依赖不能解决我的问题)我需要复制项目的所有依赖项(以jar的形式),如果我的一个jar依赖于另一个工件,也复制该工件。 示例project1 pom。xml: “project1”依赖于project2。人工制品罐子当我使用“mvn依赖项:复制依赖项”时,我得到了project2。人工制品但我没有得到project3。

  • 我给ivy添加了一个依赖项(我们称之为a)。在maven central中具有pom文件的xml。Ivy使用ibiblio来解析maven依赖项。添加到常春藤中的依赖项(A)。xml具有可传递依赖项(B)。到目前为止,一切都很好。传递依赖(B)的依赖(C)不能用常春藤来解决。 我在常春藤上定义了一个新的名字。如下所示的xml: 在B的pom文件中,C在编译和测试范围中定义如下: 当我在ivy的缓存

  • 主要内容:依赖传递,依赖范围,依赖范围对传递依赖的影响,依赖调节Maven 依赖传递是 Maven 的核心机制之一,它能够一定程度上简化 Maven 的依赖配置。本节我们将详细介绍依赖传递及其相关概念。 依赖传递 如下图所示,项目 A 依赖于项目 B,B 又依赖于项目 C,此时 B 是 A 的直接依赖,C 是 A 的间接依赖。 Maven 的依赖传递机制是指:不管 Maven 项目存在多少间接依赖,POM 中都只需要定义其直接依赖,不必定义任何间接依赖,Mav

  • 当我有一个包含POM的项目时,例如: 但是我似乎弄错了,Internet上的Maven文档并没有帮助我解决这个问题。 有什么想法吗?