SpringBoot3新功能学习
时间定在本月24日,Spring Boot将发布3.0的最终发布版本。
到目前为止,Spring Boot3已经发布了6个版本,累计发布了5个里程碑版本,以及2个RC候选版本。现在跟我来看看Spring Boot3.0将有哪些重大变化。
1. Java17
我们最关心的第一件事也是最重要的一件事是,Spring Boot3版本至少支持Java 17,是时候升级了。以下是Java 17之后的一些重要变化。
1.1 Record
record是在Java14中引入的。
在过去,我们需要编写一组get和set方法来编写类。后来Lombok
保存了这些方法。现在,Java为我们提供了本机编写方法。
public record User() {}
本质上,Record修改的类是最终的,它的父类不是Object,而是java.lang.Record
。
只能在头中声明记录类属性,所有成员变量都是公共最终变量,只能声明静态属性,但可以声明成员方法和静态方法。
public record User(String username) {
static int id;
public String getName(){
return this.username;
}
}
1.2 Text blocks
在Java 13中引入了文本块,并在Java 15中使其成为永久性的。
过去,当我们将多行字符串复制到Java时,会自动添加行终止符。
String sql = "SELECT\n" +
"\t* \n" +
"FROM\n" +
"\tsys_user0 \n" +
"WHERE\n" +
"\tuser_name = 'abc'";
文本块函数可以帮助我们更方便地定义包含多行文本的字符串文字,它使用三重引号作为开始和结束分隔符。
String sqlBlock = """ SELECT * FROM sys_user0 WHERE user_name = 'abc' """;
1.3 Switch expression
开关表达式是在Java12中引入的,并在Java14中成为永久性的。
升级后的开关包含两个功能,一个是允许案例使用多个常量,另一个是具有返回值。
新的case x->;
语法在使用上更加简洁,并且不需要为每个case编写分隔符。
String name = "Tom";
int ret = switch (name) {
case "A" -> 1;
case "Tom", "Jack" -> 2;
default -> 0;
};
1.4 Pattern Matching Pattern Matching
模式匹配可以帮助我们简化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;
};
}
1.5 Sealed sealed class
Seal是在Java 15中引入的,并成为了Java 17中的永久特性。
密封类的主要功能是限制类的继承。
例如,我们有Animal类,Dog和Cat分别继承它,并实现Eat方法。它们的进食行为是不同的,但我们不希望人们继承动物,也不允许它继承动物的进食行为,就像下面这样通过SECTED和PERMISHES关键字限制它是一个密封的类,只有猫和狗才能继承它。
需要注意的是,在父类被定义为密封后,子类必须是密封的、非密封的或最终的。
public abstract sealed class Animal permits Cat, Dog {
public abstract void eat();
}
public non-sealed class Dog extends Animal{
@Override
public void eat() {
System.out.println("dog eat");
}
}
public non-sealed class Cat extends Animal{
@Override
public void eat() {
System.out.println("cat eat");
}
}
2. Jakarta EE 9
另一个重要的变化是,在这次升级之后,它至少只支持Jakarta EE 9,使用Servlet5.0和JPA3.0规范,但最新版本RC2已经升级到JakartaEE 10,默认使用Servlet6.0和JPA3.1规范。
一些学生可能甚至不知道雅加达是什么。这个英文单词的意思是印尼首都雅加达。我们知道,Java EE在被重新命名后被称为JakartaEE。例如,我们之前的javax.Servlet
包现在称为jakarta.Servlet
。
因此,所有在代码中使用HttpServletRequest类对象的导入都需要修改。
import javax.servlet.http.HttpServletRequest;
// Change
import jakarta.servlet.http.HttpServletRequest;
3. Spring Native
Spring Native也是此次升级的一大特色。支持使用GraalVM将Spring应用编译成本地可执行的镜像文件,可以显著提高启动速度和峰值性能,减少内存使用。
我们的传统应用被编译成字节码,然后被JVM解释,最后编译成机器码运行,而Spring Native则通过AOT提前编译成机器码,并在运行时直接静态编译成可执行文件。取决于JVM。
4. Demo
在这里,我将简要演示如何使用它。一是做好一些准备工作:
然后通过Spring Initialzr创建一个新项目,使用最新版本的Spring Boot 3.0.0-SNAPSHOT,选中GraalVM Native Support
,并在创建项目后添加一个测试控制器
。
@RestController
public class TestController {
@GetMapping("/")
public String hello(){
return "GraalVM ...";
}
}
然后直接运行程序,发现启动时间大约需要1秒。
然后执行命令生成镜像文件:
./gradlew nativeCompile
这一过程相当耗时,大约需要2分钟才能生成。
最后,执行命令:
./build/native/nativeCompile/demo2
我们看到最终的启动时间是0.082秒,快了10倍以上。
这里我使用Gradle,如果您使用Maven,请使用以下命令:
1. mvnw -Pnative native:compile
2. ./target/demo2
5. 其他依赖升级
SpringBoot 3至少依赖于Spring6版本,所以对应的Spring版本也应该改变(没有人还在使用Spring2),其他依赖关系升级如下:
kotlin 1.7+
·Lombok 1.18.22+(JDK17支持版本)
·Gradle 7.3+
另外,我想说的是,SpringBoot2.7引入了一种新的自动组装方法META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
.原来的编写方法spring.Factory
在3.0版以下仍然兼容。在新版本3.0之后,不能使用旧的编写方法spring.Factory
。与中间件相关的开发,学生应该注意。
其他一些配置更改和Spring MVC中的一些小更改将不会被提及,届时可以看到更新日志。
最后,如果你想升级,在新版本发布后,会有一个基于Spring Boot 2.7版本的迁移指南。