Spring Boot 3: New Features You Need to Know

{getToc} $title={Table of Contents}

Spring Boot 3: New Features You Need to Know


Have you check out yet? About the release of Spring Boot 3, let's get into some of these new features of this release now. This major revision will be based on Spring Framework 6.0 and will require Java 17 or above. It will also be the first version of Spring Boot that makes use of Jakarta EE 9 APIs (jakarta.*) instead of EE 8 (javax.*).


Upgrade to Java 17

Spring Boot 3.0 will require Java 17, but you don’t need to wait until that release to upgrade to the latest LTS Java version. Any recent Spring Boot 2.x release will work really well with Java 17.
When migrating from LTS version 11, Java developers will benefit from new language features. Since Java itself isn't the topic of this article, we'll only name the most important new features for Spring Boot developers.

So far, Spring Boot 3 has released 6 versions, accumulatively 5 milestone versions, and 2 RC candidate versions. Now follow me to see what major changes Spring Boot 3.0 will have.


Record

The record was introduced in Java14, java records were intended to be used as a quick way to create data carrier classes, i.e. the classes whose objective is to simply contain data and carry it between modules, also known as POJOs (Plain Old Java Objects) and DTOs (Data Transfer Objects).
In the past, we needed to write a bunch of gets and set methods to write a class. Later Lombok, these methods were saved. Now Java provides us with native writing methods.


public record Dog (String color) {}

The class modified by record is final, and its parent class is not Object, but java.lang.Record.
Record class properties can only be declared in the header, all member variables are public final, and only static properties can be declared, but member methods and static methods can be declared.

public record Dog(String color) {
    static int id;
    public String getColor(){
        return this.color;
    }
}


Text Blocks

In java 13 Text Blocks were introduced and made permanent in Java15. In the past, when we copied a multi-line string to Java, line terminators would be added automatically.

private static final String SQL_GET_DOG_INFO = "SELECT\r\n" + 
    "id,\r\n" + 
    "name,\r\n" + 
    "color\r\n" + 
"FROM\r\n" + 
    "abc.dog \r\n" + 
"WHERE\r\n" + 
    "id = :DOC_ID";

Now, it's possible to create multi-line text blocks without the need to concatenate strings on line breaks.

private static final String SQL_GET_DOG_INFO = """
SELECT id,
    name,
    color
FROM
    abc.dog
WHERE
    id = :DOC_ID;
    """;


Switch Expressions

Switch expressions were introduced in Java12 and made permanent in Java14.
which (like all expressions) evaluate a single value, and can be used in statements. Instead of combining nested if–else-operators (?:).
The upgraded switch contains two features, one is to allow the case to use multiple constants, and the other is to have a return value. we can now use a switch–case-construct.

String color = "red";
int colorTxt = switch (color) {
  case "yellow" -> 1;
  case "red", "white" -> 2;
  default -> 0;
};


Pattern Matching

Pattern matching can help us simplify our instance of code. In the Java Language, they can help to simplify the code for instance of evaluations. And it can also be used in switch-case statements.

instanceof code


if (obj instanceof String text) {
    System.out.println(text.toUpperCase());
}


switch-case statements


static long getLongValueUsingSwitchSts(Object x) {
    return switch (x) {
        case Integer a -> a.longValue();
        case Float f -> f.longValue();
        case String c -> Long.parseLong(c);
        default -> 0L;
    };
}


Sealed Classes and Interfaces

Sealed was introduced in Java15 and became a permanent feature in Java17. Sealed classes can limit inheritance by specifying allowed subclasses. The main function of the sealed class is to limit the inheritance of the class.

public abstract sealed class Pet permits Dog, Cat {}

For example, we have the Animal class, Dog and Cat inherit it respectively, and implement the eat method. Their eating actions are different, but we don’t want people to inherit the Animal, and he is not allowed to inherit the animal’s eating behavior, just like the following This restricts it to be a sealed class through the sealed and permits keywords, and only cats and dogs can inherit it.

It should be noted that the subclass must be sealed, non-sealed or final after the parent class is defined as sealed.

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

Another important change is that after this upgrade, it only supports Jakarta EE 9 at least, using Servlet5.0 and JPA3.0 specifications. The most important change might be the jump from Java EE to Jakarta EE9, where the package namespace changed from javax.* to jakarta.*. As a result, we need to adjust all imports in our code whenever we use classes from Java EE directly, but the latest version RC2 has been upgraded to JakartaEE 10, using Servlet6.0 and JPA3.1 specifications by default.

For example, when we access the HttpServletRequest object within our Spring MVC Controller, we need to replace.

import javax.servlet.http.HttpServletRequest;

Change To

import jakarta.servlet.http.HttpServletRequest;

What is wht world Jakarta? This English word means Jakarta, the capital of Indonesia. We know that JavaEE is called JakartaEE after it is renamed. For example, our previous javax.servletpackage is now called jakarta.servlet.

Therefore, all imports that use objects such as HttpServletRequest in the code need to be modified.


Native Executables

Native executables and deploying them to GraalVM gets a higher priority. So the Spring Native initiative is moving into Spring proper. Spring Native is also a major feature of the upgrade. It supports using GraalVM to compile Spring applications into locally executable image files, which can significantly improve startup speed, and peak performance, and reduce memory usage.

Our traditional applications are compiled into bytecode, then interpreted by, JVM and finally compiled into machine code to run, while Spring Native is compiled into machine code in advance through AOT, and statically compiled into executable files directly at runtime. Depends on the JVM.

mvn spring-boot:aot-generate


Dependency upgrades

Spring Boot 3 depends on the Spring6 version at least, so the corresponding Spring version should also be changed (no one is still using Spring2), and other dependencies are upgraded as follows:

• Kotlin 1.7+

• Lombok 1.18.22+ (JDK17 support version)

• Gradle 7.3+

The original writing method spring.factoriesis still compatible below version 3.0. After the new version 3.0, the old writing method spring.factories cannot be used. Middleware-related development students should pay attention.


Conclusion

Some other configuration changes and some small changes in Spring MVC will not be mentioned, and the update log can be seen at that time, migrating to Spring Boot 3 and Spring 6 will be a migration to Java 17 and Jakarta EE 9 too. If we attach great importance to observability and native executables, we'll benefit the most from the upcoming major release.

Hope this is helpful.


Previous Post Next Post