vlambda博客
学习文章列表

SpringBoot3新功能学习


  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秒。

  SpringBoot3新功能学习

然后执行命令生成镜像文件:

./gradlew nativeCompile

这一过程相当耗时,大约需要2分钟才能生成。

  SpringBoot3新功能学习

最后,执行命令:

./build/native/nativeCompile/demo2

我们看到最终的启动时间是0.082秒,快了10倍以上。

  SpringBoot3新功能学习

这里我使用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版本的迁移指南。