如何在 Spring Boot 中选择性地升级依赖项? (示例案例:Spring Data)
Posted
技术标签:
【中文标题】如何在 Spring Boot 中选择性地升级依赖项? (示例案例:Spring Data)【英文标题】:How to selectively upgrade a dependency in Spring Boot? (sample case: Spring Data) 【发布时间】:2018-02-08 14:01:14 【问题描述】:我使用 Spring Boot (1.4.1) 的 Spring Data JPA starter。它包含 Spring Data JPA 1.10.3。但是,我需要使用此版本 spring 数据中尚不存在的 @DomainEvents
注释。当我尝试添加最新版本的 Spring Data JPA 时,我的应用程序运行时出现错误。
我的 pom 示例:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
...
</dependencies>
当我尝试像这样添加最新版本的 Spring Data JPA 时:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.11.6.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>
我在启动我的应用程序时遇到错误。像这样的错误:
Caused by: java.lang.NoSuchMethodException: org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.<init>()
at java.lang.Class.getConstructor0(Class.java:3082) ~[na:1.8.0_121]
at java.lang.Class.getDeclaredConstructor(Class.java:2178) ~[na:1.8.0_121]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:80) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
... 53 common frames omitted
如何使用较新版本的 Spring Data JPA?我的应用中需要@DomainEvents
。谢谢!
【问题讨论】:
您的意思是您需要更新版本的spring-data-jpa
?你说你是 Spring boot 1.4.1,它正在拉它包含 1.10.3,但你正在转向更新的版本。
您可以尝试升级发布系列,但是您可能会遇到问题,因为它还取决于较新的 Spring 版本,可能无法(完全)使用您的 JPA 版本/实现等。
真的。我没有考虑。谢谢。
【参考方案1】:
这里有多种给猫剥皮的方法,它们都有不同的优缺点:
选项 1:升级到较新版本的 Boot
总体而言,最安全的方法是升级到更新版本的 Spring Boot。我们通常建议使用当前主要版本中的最新次要版本。在您的情况下,1.5 是最新的次要版本,因此我们建议升级到该版本(当前为 1.5.6)。这通常只需更改您使用的父 pom 的版本号即可实现。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
</parent>
优点
您将自动将所有引导管理的依赖项升级到它们的最新、兼容版本。这是可取的,因为这将确保您获得第三方依赖项中安全更新的最新修复缺点
小版本升级可能需要您稍微更改配置或 API 中的内容,以防您依赖应用程序代码中的第三方 API。 Boot 中的小版本升级通常非常小心,不会在第三方库中引入重大更改,但不幸的是,并非所有升级都遵循语义版本控制。但是,如果您有一个不错的测试套件,应该很容易发现您是否会遇到问题。建议查看 release notes,因为它们通常包含迁移指南。选项 2:单独升级依赖项
前一种方法的替代方法是保持您当前的引导版本,但有选择地升级第三方依赖项。最好的方法是检查spring-boot-dependencies 中存在哪些版本占位符。然后你只需要在你的项目中重新声明属性并调整版本。对于 Spring Data,那就是:
<properties>
<spring-data-releasetrain.version>Ingalls-SR6<spring-data-releasetrain.verion>
</properties>
如果是 Spring Data,您将在此处一次升级整个发布系列,这样如果您只升级一个模块,就不会在内部遇到 Spring Data 模块之间的不兼容问题。这是建议“按属性升级”而不是在较新版本中明确重新声明依赖项的主要原因之一(在某些情况下,这仍然是最后的手段)。
优点
升级操作更具选择性。与以前的方法相比,您不会冒着遇到无关依赖项的升级问题的风险。缺点
它可能不起作用! - 有时依赖项会更改 Boot 的自动配置在次要版本中依赖的一些内部 API。这可能会导致自动配置在启动时不起作用,您可以尝试通过明确排除自动配置并编写手动配置来替换它。建议步骤
在实践中我通常会尝试以下步骤:
-
使用选项 1 进行升级时影响尽可能小。如果成功:完成。
如果这会导致问题,请评估将自动配置替换为手动配置的难度(通常需要对 Boot 有一些了解和经验。如果成功:完成。
使用选项 2 升级到较新版本的 Boot 并评估这对您的应用程序代码的影响。
2 和 3 可能可以互换,具体取决于您个人的偏好或您为团队定义的依赖项升级策略。
一般来说,密切关注 Boot 版本并定期尝试将项目干升级到较新版本是一个好主意,但不一定要将升级发布到生产环境。这使您可以评估升级的风险并估计需要进行的工作量。 避免升级基本上只会让升级更加痛苦,但是,有时由于政治原因或升级在新版本中遇到问题,无法立即进行升级。
【讨论】:
谢谢。在发布序列级别升级(例如 - spring-data)也会同时升级多个客户端库。并非总是可以同时升级所有解决方案,以支持任何/某些其他提供商的升级。例如spring-boot.2.0.X
支持ElasticSearch 5.5..X
和Kafka 1.0.X
;现在如果我需要将Kafka
升级到2.0.X
,则必须使用与ElasticSearch 6.0.X
兼容的spring-boot 2.1.X
;但我可能不需要ElasticSearch
版本升级。我们如何处理此类案件?选择性覆盖版本是有风险的,不是吗?
是的。您可能可以升级到 Boot 2.1,但将 Spring Data 降级到 Kay 并进行测试。根据您正在使用的模块,您可能会看到这是有效的,因为我们正在努力尽量减少对 Boot 的 API 更改。在某些情况下,我们没有太多选择,因为数据库客户端会大幅更改 API。以上是关于如何在 Spring Boot 中选择性地升级依赖项? (示例案例:Spring Data)的主要内容,如果未能解决你的问题,请参考以下文章
升级后的 Spring Boot Oauth2 自动配置周期
升级到 Spring Boot 2.5.1 和 Spring Cloud 2020.0.3 时,Netflix zuul 和 Ribbon 的 Maven 依赖项有啥不同吗