当前位置: 首页 > news >正文

JDK 8 → JDK 17 升级说明书(面向 Spring Boot / Spring Cloud / Spring )

自从 JDK 8 发布以来,Java 语言在持续进化,带来了许多新的功能和性能改进。而 JDK 17 作为一个长期支持版本(LTS),在许多方面超越了 JDK 8,不仅提升了语言本身的能力,还进一步提高了性能、可维护性和开发者体验。

1 背景与功能增强

公司核心系统当前基于:

  • JDK 1.8
  • Spring Boot 2.x / Spring Cloud 2021.x
    官方已于 2022 年宣布:

Spring Framework 6、Spring Boot 3、Spring Cloud 2022+ 最低要求 JDK 17
继续留在 JDK 8 将永久锁定在 2.x 维护分支,无法获得任何新特性与安全补丁。

1.Spring 官方强制基线

  • Spring Framework 6.x:仅支持 JDK 17+
  • Spring Boot 3.x:最低 JDK 17,默认内置 Native/CDS 优化
  • Spring Cloud 2022+:基于 Boot 3,提供 Gateway 4、K8s Config 2.0 等新组件

停留在 JDK 8 = 永久错过新功能与社区长期维护。

2.模块化系统(JDK 9 引入,JDK 17 强化)

在 JDK 9 中引入了 Java 平台的模块化系统,它通过 module 关键字帮助开发者将代码组织成不同的模块,从而提升代码的可维护性、可扩展性和安全性。JDK 17 在模块系统方面进行了更多优化,使得模块化的使用更加高效。

  • JDK 8:没有模块化系统,所有代码都在一个大的类库中。
  • JDK 17:模块化系统已经成熟,Java 平台本身被拆分为多个模块,可以灵活选择需要的模块,大大减少了 JDK 的体积,提高了应用的启动性能。
示例代码:
module com.myapp {requires java.base;exports com.myapp.service;
}

3.Lambda 表达式与 Stream API(JDK 8 引入)

JDK 8 引入了 Lambda 表达式和 Stream API,极大简化了函数式编程和集合操作的语法。JDK 17 在此基础上优化了性能和流操作的稳定性,尤其在处理大量数据时,提供了更好的支持。

  • JDK 8:Lambda 表达式和 Stream API 支持函数式编程,简化了集合的操作。
  • JDK 17:增强了 Stream API 和 Lambda 表达式的性能,特别是在并行流操作和垃圾回收方面。

4.记录类(JDK 14 引入)

JDK 14 引入了记录类(record),这是一个简化 Java Bean 类的语法。它使得不需要编写大量的模板代码(如 getter、setter、equals、hashCode 等方法)。在 JDK 17 中,记录类的支持变得更加完善,尤其是对继承和序列化的支持。

  • JDK 8:没有记录类,需要手动编写 getter、setter、equals 和 hashCode 方法。
  • JDK 17:使用 record 关键字定义不可变对象,自动生成常用方法,减少样板代码,提高可读性。
示例代码:
public record Person(String name, int age) {}

5.增强的 switch 表达式(JDK 12 引入)

JDK 12 引入了增强的 switch 表达式,这使得 switch 更加灵活,支持返回值、块语句和 yield 语句。JDK 17 中进一步优化了 switch 表达式的性能和功能,提升了代码的可维护性。

  • JDK 8switch 只能用作控制结构,无法返回值或执行多条语句。
  • JDK 17:增强的 switch 表达式允许返回值、使用块语句,并支持 yield 语句来返回结果
示例代码:
int day = 3;
String result = switch (day) {case 1 -> "Sunday";case 2 -> "Monday";default -> throw new IllegalStateException("Invalid day: " + day);
};

6、var 关键字(JDK 10 引入)

JDK 10 引入了 var 关键字,允许在声明变量时让编译器根据初始化值推断类型。这大大减少了样板代码,增强了代码的简洁性和可读性。在 JDK 17 中,var 关键字支持了更多的上下文,进一步简化了代码。

  • JDK 8:没有 var 关键字,所有变量都必须显式声明类型。
  • JDK 17var 关键字被广泛应用于局部变量声明和增强的 lambda 表达式中,减少了冗余的类型声明。

示例代码:

var message = "Hello, Java!";
var list = new ArrayList<String>();

7.JVM 性能与垃圾回收改进

JDK 8 和 JDK 17 在 JVM 性能和垃圾回收(GC)方面有显著差异。JDK 17 默认启用了更先进的垃圾回收器(例如 G1 GC 和 ZGC),这些改进使得内存管理更加高效,并减少了 GC 停顿时间。

  • JDK 8:默认使用 Parallel GC,适用于大部分应用场景,但在响应时间要求高的场景下可能表现不佳。
  • JDK 17:引入了 ZGC(Z Garbage Collector),在低延迟应用中表现优异,能够处理非常大的堆内存。

8.、文本块(JDK 13 引入)

JDK 13 引入了文本块(text block)功能,这使得多行字符串文本的编写变得更加简洁和可读。文本块支持原始文本格式,使得嵌套 JSON 或 SQL 查询变得更加直观。

  • JDK 8:多行字符串需要使用字符串连接符 +,使得代码不易阅读。
  • JDK 17:支持多行字符串文本(text block),大大提升了代码的可读性和简洁性。

示例代码:

String json = """{"name": "John","age": 30,"city": "New York"}""";

9.增强的 PatternMatcher API(JDK 16 引入)

JDK 16 引入了对正则表达式的增强支持,尤其是 PatternMatcher 类的增强,使得在处理复杂的正则表达式时更加灵活和高效。

  • JDK 8:正则表达式库功能较为基础。
  • JDK 17:增强了正则表达式的语法支持,包括非捕获分组和更复杂的匹配模式。

10.sealed 类(JDK 15 引入)

sealed 类(密封类)是在 JDK 15 中引入的一个特性,它允许类设计者限制哪些类可以继承它们。这个特性为 Java 提供了更强的类型系统,能够确保类层次结构的封闭性。

  • JDK 8:没有 sealed 类,所有类可以自由继承。
  • JDK 17:支持 sealed 类,类设计者可以限制子类的继承,从而增强代码的可控性和安全性。

示例代码:

public sealed class Shape permits Circle, Square {}
public final class Circle extends Shape {}
public final class Square extends Shape {}

11.JEP 389:外部内存访问 API(JDK 16 引入)

JDK 16 引入了外部内存访问 API,它为 Java 提供了一种更高效的方式来访问外部内存(即不在 Java 堆中的内存),这个特性对于与本地代码或操作系统交互时的性能优化非常重要。

  • JDK 8:不提供对外部内存的直接访问。
  • JDK 17:通过 MemorySegmentMemoryAddress 等 API,Java 现在可以更高效地与外部内存交互。

2 升级计划

整个升级过程 计划分为3步。

  • step1:先将项目升级到jdk17,使用正常
  • step2:生成代码的模板类升级到Jdk17对应的版本
  • step3:功能陆续验证

原项目版本:Jdk8 + springboot 2.x.x.x

升级后版本:Jdk17 + springboot 3.x.x

2.1 基础依赖升级
1. 首先把项目环境切换到Jdk17上


 

2. 父级pom文件中spring-boot-starter-parent版本升级到3.x.x

<properties>

<spring.boot.version>3.1.0</spring.boot.version>

</properties>

3. 项目配置中的java.version由8升级到17

<properties>

<java.version>17</java.version>

</properties>

4. maven编译相关maven.compiler.sourcemaven.compiler.target由8升到17

<properties>

<maven.compiler.source>17</maven.compiler.source>

<maven.compiler.target>17</maven.compiler.target>

</properties>

5. 由于在jdk17中移除了javax的部分包,所以很多javax.xxx都需要修改jakarta.xxx

新版 Jakarta EE 10 对 Spring Boot 3 的相关依赖进行了更新:

  • Servlet 规范更新至 6.0。
  • JPA 规范更新至 3.1。

因此,如果我们未通过 spring-boot-starter 来自动管理这些依赖的版本,我们就应该手动更新它们。

首先更新 JPA 依赖:

<dependency><groupId>jakarta.persistence</groupId><artifactId>jakarta.persistence-api</artifactId><version>3.1.0</version>
</dependency>

最新版本的 jakarta.persistence-api 可从 Maven Central 获取。

接下来更新 Servlet 依赖:

<dependency><groupId>jakarta.servlet</groupId><artifactId>jakarta.servlet-api</artifactId><version>6.0.0</version>
</dependency>

最新版本的 jakarta.servlet-api 可从 Maven Central 获取。

除了依赖坐标的变化外,Jakarta EE 现在使用 jakarta 包而不是 javax 包。因此,更新依赖后,我们可能需要更新 import 语句。

6. 如果我们未通过 spring-boot-starter 来管理 Hibernate 的依赖版本,那么一定要手动更新其版本:
<dependency><groupId>org.hibernate.orm</groupId><artifactId>hibernate-core</artifactId><version>6.1.4.Final</version>
</dependency>

最新版本的 hibernate-core 可从 Maven Central 获取。

7. lombok版本由1.18.20 升级 1.18.30

2.2 相关组件升级
部分属性的修改:

部分属性的修改:

  • spring.redis 已移至 spring.data.redis
  • spring.data.cassandra 已移至 spring.cassandra
  • 移除了spring.jpa.hibernate.use-new-id-generator
  • server.max.http.header.size 已移至 server.max-http-request-header-size
  • 移除了对 spring.security.saml2.relyingparty.registration.{id}.identity-provider 的支持。

要识别这些属性,我们可以在 pom.xml 中添加 spring-boot-properties-migrator

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-properties-migrator</artifactId><scope>runtime</scope>
</dependency>

最新版本的 spring-boot-properties-migrator 可从 Maven Central 获取。

该依赖会在启动时生成并打印一份报告,列出已废弃的属性名称,并在运行时临时迁移这些属性。

其他变化

此外,该版本还包括一些其他重大的核心变化:

  • 移除图像 banner 支持:要自定义 banner,只有 banner.txt 文件才被视为有效文件。
  • 日志中的日期格式:Logback 和 Log4J2 的新默认日期格式为 yyyy-MM-dd'T'HH:mm:ss.SSSXXX 如果要恢复旧的默认格式,我们需要将 application.yaml 中的属性 logging.pattern.dateformat 的值设置为旧值。
  • @ConstructorBinding 只在构造函数上使用:对于 @ConfigurationProperties 类,不再需要在类上使用 @ConstructorBinding,并且应该将其移除。然而,如果一个 class 或 record 有多个构造函数,则必须在所需的构造函数上使用 @ConstructorBinding 来指定哪个构造函数将用于属性绑定。
security

Spring Boot 3 仅与 Spring Security 6 兼容。

在升级到 Spring Boot 3.0 之前,我们应该先 将 Spring Boot 2.7 应用升级到Spring Security 5.8。然后,我们可以将 Spring Security 升级到版本 6,并升级到 Spring Boot 3.0。

该版本中引入了一些重要更改:

  • ReactiveUserDetailsService 未自动配置:在存在 AuthenticationManagerResolver 的情况下,ReactiveUserDetailsService 不再自动配置。
  • SAML2 依赖方配置:我们之前提到,新版 Spring boot 不再支持 spring.security.saml2.relyingparty.registration.{id}.identity-provider 下的属性。相反,我们应该使用 spring.security.saml2.relyingparty.registration.{id}.asserting-party 下的新属性。

3 版本对应

JDK版本与Spring Boot版本对应

Maven版本与Spring Boot版本对应

SpringCloud与SpringBoot版本对应

项目大致依赖

springcloud相关组件

http://www.dtcms.com/a/352362.html

相关文章:

  • Filter过滤器入门
  • android 事件处理源码
  • 当 AI 走进日常:除了聊天机器人,这些 “隐形应用” 正在改变我们的生活
  • 报告:2025机器人技术产业化研究|附130+份报告PDF、数据仪表盘汇总下载
  • 直播到AI助教:在线教育系统源码如何重塑知识付费平台生态?
  • 算法练习——26.删除有序数组中的重复项(golang)
  • 电影感氛围人像风光摄影后期Lr调色教程,手机滤镜PS+Lightroom预设下载!
  • 抖音多账号管理平台哪家比较好?
  • 力扣 30 天 JavaScript 挑战 第40天 (第十一题)对纯函数和记忆函数有了更深理解
  • ABC420A-E题解
  • Zynq开发实践(FPGA之verilog仿真)
  • leetcode算法刷题的第十八天
  • 【世纪龙科技】职业院校汽车专业职业体验中心建设方案
  • 面试题随笔
  • 微服务-25.网关登录校验-网关传递用户到微服务
  • 微服务的编程测评系统16-用户答题
  • 【typenum】30 类型级别的取负(Neg)
  • `mmap` 系统调用详解
  • 设备驱动程序 day62
  • 变压器副边电流计算
  • es-toolkit 是一个现代的 JavaScript 实用库
  • 15公里图传模组:为远程飞行赋能,突破极限的无线连接新选择
  • 微服务-28.配置管理-共享配置
  • 微服务-26.网关登录校验-OpenFeign传递用户信息
  • 前端RSA加密库优缺点总结
  • 42_基于深度学习的非机动车头盔佩戴检测系统(yolo11、yolov8、yolov5+UI界面+Python项目源码+模型+标注好的数据集)
  • Python内存模型与对象系统深度解析
  • 使用Kiro智能开发PYTHON应用程序
  • 25072班8.26日数据结构作业
  • 【CFA三级笔记】资产配置:第一章 资本市场预期(宏观分析)