spring - 为什么 Spring Boot 启动器依赖项被设计为与 Maven 传递依赖机制的既定意图相反?

标签 spring maven spring-boot dependency-management maven-dependency-plugin

根据Maven dependency documentation旨在显式列出所有编译依赖项,而不是在编译时传递使用:

it is intended that [transitive compile dependencies] should be runtime scope instead, so that all compile dependencies must be explicitly listed - however, there is the case where the library you depend on extends a class from another library, forcing you to have available at compile time. For this reason, compile time dependencies remain as compile scope even when they are transitive.

Spring Boot 有一个“Starter”依赖的概念。从 Spring Boot 自己的文档(以及我在 Spring Boot 自己的示例和其他地方看到的许多使用示例)中,很明显这些旨在传递地引入许多其他依赖项,以便在运行时和编译时使用.根据 Spring Boot's documentation :

Starters are a set of convenient dependency descriptors that you can include in your application. You get a one-stop-shop for all the Spring and related technology that you need, without having to hunt through sample code and copy paste loads of dependency descriptors. For example, if you want to get started using Spring and JPA for database access, just include the spring-boot-starter-data-jpa dependency in your project, and you are good to go.

The starters contain a lot of the dependencies that you need to get a project up and running quickly and with a consistent, supported set of managed transitive dependencies.

使用这种机制传递地引入编译范围的依赖项似乎与 Maven 官方打算如何使用它们的意图不一致。一个非常清楚的地方是 Maven dependency:analyze插件目标,当直接使用 Maven 启动器依赖项时显示警告。例如,在 Spring Boot 自己的“Getting Started”示例上运行 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 启动器模式的设计方式与底层构建系统的既定意图直接相反。是否有关于该主题的任何已发布讨论,或在任何地方给出的解释?

最佳答案

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

Comment :

Why was the Spring Boot starter pattern was designed in such a way to be directly contrary to the intent of the underlying build system?

IMO,您对 Maven 文档中的一个句子读得太多了。我认为这说明即使被警告你也必须选择加入。

Is there a reason it was felt that this misuse is "OK"?

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

Is there a "correct" way that this functionality — conveniently providing a set of dependencies at set known versions with a single simple Maven configuration — would better be implemented?

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

Comment :

You are overreading this and your point of view lack of practicability IMO. The dependency:analyze goal was a mean to offer users a way to detect that your compilation classpath only contains what you actually need. This sentence in the doc is merely there to explain why the compile scope is transitive as well.

[...]

In retrospective, you're having a Maven question and not a Spring Boot questions because tons of projects out there not using Spring Boot do not list all their compile dependencies themselves.

根据此反馈,票证 MDEP-557已为 Maven 依赖插件创建,不会对这些传递依赖的使用发出警告。

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

关于spring - 为什么 Spring Boot 启动器依赖项被设计为与 Maven 传递依赖机制的既定意图相反?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27994153/

相关文章:

spring - JSF-SPRING-HIBERNATE 架构 - 与支持 bean 相关的最佳实践

wcf - 在事务提交之前触发 Spring AfterReturningAdvice

spring - 队列 channel 初始化为 SubscribableChannel

使用 Spring 的 Maven 多模块项目出现 java.lang.NoClassDefFoundError

java - key 斗篷 : Get notified via API when a new user registers

java - 转换 Query.getResultList() 的输出

Maven - 如何执行条件执行

java - Maven多模块项目的构建顺序?

java - Spring EntityManager.persist 问题

spring - 在非 spring 应用程序中使用 spring 应用程序作为库