写点什么

SpringBoot3 正式版将于 11 月 24 日发布:都有哪些新特性?

作者:艾小仙
  • 2022-11-14
    上海
  • 本文字数:3088 字

    阅读完需:约 10 分钟

从 2018 年 2 月 28 号发布 Spring Boot 2.0 版本开始,整个 2.X 版本已经经过了 4 年多的时间,累计发布了 95 个不同的版本,而就在前不久,2.X 系列的也已经迎来了他的最终版本:2.7。


前几天我还写了一篇关于 Spring Boot 从 2.1 版本升级到 2.7 的文章,而现在,Spring Boot 3.0 也要来了!


时间就定在本月的 24 号,Spring Boot 将要发布 3.0 的最终 RELEASE 版本。


截止到现在为止,Spring Boot3 已经发布了 6 个版本,累计 5 个里程碑版本,2 个 RC 候选版,现在就跟着我一起看下 Spring Boot 3.0 将会要哪些重大的变化。

JAVA 17

对于我们比较关注的第一个最重要的事情就是,Spring Boot3 版本最低支持 Java17,还在万年 Java8 的同学,该升级就升级了吧,这里介绍一下关于 Java17 之后的一些重要改变。

record

record 是在 Java14 中引入的,https://openjdk.org/jeps/395


以前我们写一个类需要写一堆 get、set 方法,后来有了lombok之后这些都省了,现在 Java 给我们提供了原生的写法。


public record User() {}
复制代码


本质上 record 修饰之后的类就是一个 final 类,而且他的父类不是 Object,也不是余某军,而是 java.lang.Record


record 类属性只能声明在头部,所有的成员变量都是 public final 的,而且只能声明静态属性,但是可以声明成员方法和静态方法。


public record User(String username) {    static int id;    public String getName(){        return this.username;    }}
复制代码

text blocks

text blocks 文本块是在 Java13 引入的,并且在 Java15 版本成为永久特性,https://openjdk.org/jeps/378


以前我们复制一个多行的字符串到 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'                """;
复制代码

switch 表达式

switch 表达式是在 Java12 中引入的,在 Java14 成为永久特性,https://openjdk.org/jeps/361


升级后的 switch 其实包含两个特性,一个是允许 case 使用多个常量,另外一个就是有返回值。


新增case x-> 语法,使用方面更加简洁,而且不需要再每个 case 写一个 break 了。


String name = "xiao";int ret = switch (name) {  case "ai" -> 1;  case "xiao", "xian" -> 2;  default -> 0;};
复制代码

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;    };}
复制代码

sealed 密封类

sealed 在 Java15 中引入,在 Java17 成为永久特性。


sealed 密封类的主要作用就是限制类的继承。


比如我们有 Animal 类,Dog 和 Cat 分别继承它,实现了 eat 方法,他们吃的动作是不一样的,但是我们不希望人能继承 Animal,不允许他去继承动物吃的行为,就可以像下面这样通过 sealed 和 permits 关键字限制它是一个密封类,只有猫和狗能够继承它。


需要注意,父类被定义为 sealed 之后,子类必须是 sealed、 non-sealed 或者 final。


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"); }}
复制代码

Jakarta EE 9

另外一个很重要的变化就是本次升级之后,最低只支持 Jakarta EE 9,使用 Servlet5.0 和 JPA3.0 规范,不过最新版本 RC2 已经升级到了 JakartaEE 10,默认使用 Servlet6.0 和 JPA3.1 规范。


有些同学可能连 Jakarta 是什么都不知道,这个英文单词是印尼首都雅加达的意思,其实就是我们知道的 JavaEE 改名之后就叫 JakartaEE,比如我们之前的javax.servlet包现在就叫jakarta.servlet


也因此,代码中所有使用到比如 HttpServletRequest 对象的 import 都需要修改。


import javax.servlet.http.HttpServletRequest;改为import jakarta.servlet.http.HttpServletRequest;
复制代码

Spring Native

Spring Native 也是升级的一个重大特性,支持使用 GraalVM 将 Spring 的应用程序编译成本地可执行的镜像文件,可以显著提升启动速度、峰值性能以及减少内存使用。


我们传统的应用都是编译成字节码,然后通过 JVM 解释并最终编译成机器码来运行,而 Spring Native 则是通过 AOT 提前编译为机器码,在运行时直接静态编译成可执行文件,不依赖 JVM。


关于 AOT 技术,在我之前写过的文章中有提及到:这样优化Spring Boot,启动速度快到飞起!

演示

这里我简单演示一下怎么使用,首先我们需要做一些准备工作:


  1. https://www.graalvm.org/downloads/ 下载 GraalVM,指定JAVA_HOME,export JAVA_HOME=/Users/user/Desktop/graalvm-ce-java17-22.3.0/Contents/Home

  2. 下载个新一点的 IDEA,比如我使用的是最新的 EAP 版本

  3. 下载个新一点的 JDK,比如使用 JDK17


然后通过 Spring Initialzr 创建一个新项目,使用最新版本 Spring Boot 3.0.0-SNAPSHOT,勾选GraalVM Native Support,创建好项目之后添加一个测试的Controller


@RestControllerpublic 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:compile2. ./target/demo2
复制代码

其他依赖升级

Spring Boot 3 最低依赖 Spring6 版本,因此对应的 Spring 版本也该换了(不会有人还在用 Spring2 的吧),其他的依赖升级如下:


  • Kotlin 1.7+

  • Lombok 1.18.22+ (JDK17 support 支持版本)

  • Gradle 7.3+


另外我想说的是,SpringBoot2.7 引入了新的自动装配方式META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports,原来的写法spring.factories在 3.0 版本以下还能兼容,3.0 新版本之后,老的写法spring.factories不能使用了,中间件相关的开发同学要注意了。


其他一些关于配置的变化,Spring MVC 的一些小变化就不说了,更新日志到时候都可以看到。


最后,如果想升级的话,在新版本发布之后,会有一个基于 Spring Boot 2.7 版本的迁移指南。


参考:

  1. https://www.baeldung.com/spring-boot-3-spring-6-new

  2. https://blogs.oracle.com/java/post/go-native-with-spring-boot-3-and-graalvm

  3. https://spring.io/blog/2022/05/24/preparing-for-spring-boot-3-0

  4. https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Release-Notes

发布于: 刚刚阅读数: 4
用户头像

艾小仙

关注

公众号:艾小仙。阿里P7,编程修仙 2020-09-01 加入

公众号:艾小仙

评论

发布
暂无评论
SpringBoot3正式版将于11月24日发布:都有哪些新特性?_Java_艾小仙_InfoQ写作社区