spring-boot Unwrapped: Exploring the Latest Features

Main features

Structured logging

Log in JSON format.

logging.structured.format.console=ecs
logging.structured.format.file=ecs

Support for:

  • Elastic Common Schema (ECS)
  • Gralog Extended Log Format (GELF)
  • Logstash

Metrics with micrometer

java virtual threads

spring.threads.virtual.enabled=true

No code changes required.

Client support

RestClient: Synchronous HTTP client.

restClient.get()
    .uri("/speakers/{slug}", slug)
    .retrieve()
    .body(Speaker.class);

Client autoconfiguration:

  • Apache HTTP components
  • Jetty client
  • Reactor netty
  • JDK
  • Simple JDK

JdbcClient: unified facade for query/update statement on top of JdbcTemplate.

jdbcClient.sql("SELECT * FROM speaker WHERE slug = :slug")
    .param("slug", slug)
    .query(Speaker.class)
    .optional();

Client in spring AI.

chatClient.prompt()
    .user("what is the most popular fiction book in 2024?")
    .call()
    .entity(Book.class);

Actuator

Info contributors

New info contributors: Endpoints Spring Boot.

management:
  info:
    process.enabled: true
    ssl.enabled: true
    java.enabled: true
    os.enabled: true
    env.enabled: true
    git.enabled: true
  endpoints:
    web:
      exposure:
        include: info, health, loggers
  endpoint:
    loggers:
      access: read_only # none | read_only | unrestricted

SBOM endpoint

  • Exposes the Software Bill of Materials.
  • CycloneDX SBOMs auto-detected maven and Gradle plugins.
<build>
  <plugins>
    <plugin>
      <groupId>org.cyclonedx</groupId>
      <artifactId>cyclonedx-maven-plugin</artifactId>
    </plugin>
  </plugins>
</build>
GET /actuator/sbom/application

Scheduled tasks endpoint

GET /actuator/scheduledtasks

Package

Improvements in OCI containers.

Now uses paketobuildpacks/builder-jammy-java-tiny builder, which does not include a shell. 23% smaller container.

ARM containers.

mvn spring-boot:build-image \
  -Dspring-boot.build-image.imagePlatform=linux/arm64 \
  -Dspring-boot.build-image.imageName=foo/bar:1.0.0

CDS

Class Data Sharing. Start your application faster and consume less memory.

Training run CDS archive Production run

Exploded JAR

Running CDS on an executable JAR is not recommended:

  • loading classes from nested jars has a startup cost
  • running the app from an exploded JAR is faster and recommended in prod
java -Djarmode=tools -jar foobar.jar extract --destination application

CDS archive

spring-boot offers a convenient way to build a CDS archive.

java \
  -XX:ArchiveClassesAtExit=./application.jsa \ # create an archive of classes
  -Dspring.context.exit=onRefresh \ # start and immediately exit the application
  -jar application/foobar.jar

Running with CDS

  • Specify the CDS archive when running the application.
  • Some constraints:
    • Must use the same JVM utilized for creating the archive.
    • Same classpath.
java -XX:SharedArchiveFile=application.jsa -jar application/foobar.jar

CDS and buildpacks

  • Performs automatically the training run.
  • Extract the spring-boot executable JAR to the CDS friendly file layout.
  • Adds the CDS archive in the container.
  • Automatically enables CDS when running the container image.

The CDS training run is performed transparently when building the container image with the same JVM used at runtime!

<plugin>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-maven-plugin</groupId>
  <configuration>
    <image>
      <env>
        <BP_JVM_CDS_ENABLED>true</BP_JVM_CDS_ENABLED>
      </env>
    </image>
  </configuration>
</plugin>

Testing

Bean overriding support and MockMvcTester.

  • spring-boot disables bean definition overriding by default.
  • TestContext framework introduces new bean overriding support.
    • Based on @BeanOverride meta-annotation and associated infrastructure.
    • @TestBean, @MockitoBean and @MockitoSpyBean

@TestBean

@TestBean allows overriding a specific bean in the tests ApplicationContext by providing a static factory method.

@SpringBootTest
class OverrideBeanTest {
  @TestBean
  TestService testService;
 
  static TestService testService() {
    return StubTestService();
  }
}

@MockitoBean

@MockBean is deprecated in favor of @MockitoBean.

@SpringBootTest
class OverrideBeanTest {
  // Replaces the bean of type CustomService with a mock.
  @MockitoBean
  CustomService customService;
 
  // Replace the bean named service with a mock.
  @MockitoBean("service")
  CustomService customService;
}

MockMvcTester

  • The new MockMvcTester uses assertj.
  • @AutoConfigureMockMvc and @WebMvcTest autoconfigures:
    • MockMvc
    • MockMvcTester if assertj is on the classpath.

Other features

  • Graceful shutdown by default.
  • Fragment rendering.
  • Background bean initialization.
  • Fallback beans.
  • Content negotiation for @ExceptionHandler methods.
  • testcontainers improvements.

You can use OpenRewrite to automate the migration to spring-boot 3.3, but it also supports other tools/libraries/frameworks.