1. 概述
距离Spring Boot 3的发布只有很短的时间了,现在似乎是查看新功能的好时机。
2. Java 17
虽然之前已经支持Java 17,但这个LTS版本现在有了基线。
从LTS版本11迁移时,Java开发人员将受益于新的语言特性。由于Java本身不是本文的主题,因此我们将只列出对Spring Boot开发人员最重要的新功能。我们可以在Java 17、16、15、14、13和12的单独文章中找到更多详细信息。
2.1 记录
Java记录(JEP 395,请参阅Java 14 Record关键字)旨在用作创建数据载体类的快速方法,即其目标是简单地包含数据并在模块之间传输数据的类,也称为POJO(Plain Old Java Object)和DTO(Data Transfer Objects)。
我们可以轻松创建不可变的DTO:
public record Person(String name, String address) {
}
目前,我们在将它们与Bean Validation结合使用时需要小心,因为构造函数参数不支持验证约束,例如在JSON反序列化(Jackson)上创建实例并作为参数放入控制器的方法时。
2.2 文本块
使用JEP 378,现在可以创建多行文本块,而无需在换行符处拼接字符串:
String textBlock = """
Hello, this is a
multi-line
text block.
""";
2.3 Switch表达式
Java 12引入了switch表达式(JEP 361),它(像所有表达式一样)计算单个值,并且可以在语句中使用。我们现在可以使用switch–case构造,而不是组合嵌套的if–else运算符(?:):
DayOfWeek day = DayOfWeek.FRIDAY;
int numOfLetters = switch (day) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
case THURSDAY, SATURDAY -> 8;
case WEDNESDAY -> 9;
};
2.4 模式匹配
模式匹配在Project Amber中得到了详细阐述,并找到了进入Java语言的方式。在Java语言中,它们可以帮助简化instanceof求值的代码。
我们可以直接将它们与instanceof一起使用:
if (obj instanceof String s) {
System.out.println(s.toLowerCase());
}
我们也可以在switch–case语句中使用它:
static double getDoubleUsingSwitch(Object o) {
return switch (o) {
case Integer i -> i.doubleValue();
case Float f -> f.doubleValue();
case String s -> Double.parseDouble(s);
default -> 0d;
};
}
2.5 密封类和接口
密封类可以通过指定允许的子类来限制继承:
public abstract sealed class Pet permits Dog, Cat {
}
我们可以在Java中的密封类和接口中找到更多详细信息。
3. Jakarta EE 9
最重要的变化可能是从Java EE升级到Jakarta EE 9,其中包命名空间从javax.*更改为jakarta.*。因此,每当我们直接使用Java EE中的类时,我们都需要调整代码中的所有导入。
例如,当我们在Spring MVC Controller中访问HttpServletRequest对象时,我们需要替换:
import javax.servlet.http.HttpServletRequest;
为:
import jakarta.servlet.http.HttpServletRequest;
当然,我们不必经常使用Servlet API的类型,但是如果我们使用Bean Validation和JPA,那么这是不可避免的。
当我们使用依赖于Java/Jakarta EE的外部库时,我们也应该意识到这一点(例如,我们必须使用Hibernate Validator 7+、Tomcat 10+和Jetty 11+)。
4. 进一步的依赖
Spring Framework 6和Spring Boot 3需要以下最低版本:
- Kotlin 1.7+
- Lombok 1.18.22+(JDK 17支持)
- Gradle 7.3+
5. 主要关注点
两个首要主题受到了特别关注:本机可执行文件和可观察性。总体意味着:
- Spring框架引入了核心抽象
- 投资组合项目始终与他们整合
- Spring Boot提供自动配置
5.1 本机可执行文件
构建本机可执行文件并将它们部署到GraalVM获得更高的优先级,所以Spring Native倡议正在进入Spring本身。
对于AOT生成,不需要包含单独的插件,我们可以使用spring-boot-maven-plugin的新目标:
mvn spring-boot:aot-generate
Native Hints也将成为Spring核心的一部分。Milestone 5(v6.0.0-M5)将提供为此的测试基础设施。
5.2 可观察性
Spring 6引入了Spring Observability-一项建立在Micrometer和Micrometer Tracing(以前称为Spring Cloud Sleuth)基础之上的新计划。目标是使用Micrometer有效地记录应用程序指标,并通过OpenZipkin或OpenTelemetry等提供程序实施跟踪。
Spring Boot 3中对所有这些进行了自动配置,并且Spring项目正在努力使用新的Observation API进行自我检测。
我们可以在专门的文章中找到有关它的更多详细信息。
6. Spring Web MVC中的小改动
最重要的新功能之一是对RFC7807(问题详细信息标准)的支持。现在我们不需要包含单独的库,例如Zalando Problem。
另一个较小的变化是HttpMethod不再是一个枚举,而是一个允许我们为扩展的HTTP方法创建实例的类,例如那些由WebDAV定义的:
HttpMethod lock = HttpMethod.valueOf("LOCK");
至少删除了一些过时的基于Servlet的集成,例如Commons FileUpload(我们应该使用StandardServletMultipartResolver进行Multipart文件上传)、Tiles和FreeMarker JSP支持(我们应该使用FreeMarker模板视图)。
7. 迁移项目
我们应该了解一些项目迁移的提示。推荐的步骤是:
- 迁移到Spring Boot 2.7(等Spring Boot 3发布时,会有基于Spring Boot 2.7的迁移指南)
- 检查不推荐使用的代码使用和遗留配置文件处理;它将随着新的主要版本被删除
- 迁移到Java 17
- 检查第三方项目是否有Jakarta EE 9兼容版本
- 由于Spring Boot 3尚未发布,我们可以尝试使用当前里程碑来测试迁移
8. 总结
正如我们所了解到的,迁移到Spring Boot 3和Spring 6也将是迁移到Java 17和Jakarta EE 9,如果我们非常重视可观察性和本机可执行文件,我们将从即将发布的主要版本中获益很多。
与往常一样,本教程的完整源代码可在GitHub上获得。