Spring Boot 3.0: What to Expect and How to Prepare

by Hristina Nastevska

12 min read

It's time for an upgrade: Spring Boot 3.0 will be released this November. Since most Java-based production applications and Java developers are using it, we need to discuss what we can expect in this version and how to prepare for it appropriately. 

What Is Spring Boot?

Spring Boot is an open-source extension of the powerful Spring Framework that helps you jump-start your application for production. It's a bundle with third-party libraries for the sole purpose of making the developer's work easier and allows overall focus on the application's business logic rather than on configuration; that's why Spring Boot is an excellent choice.

Spring Boot is created by Pivotal Software, and they have major Spring Boot releases of the micro-framework every four years. Spring Boot 1.0 was released in 2014, and Spring Boot 3.0 is planned to be released in 2022. So, let's see the Spring Boot tutorial about the new version and how to prepare.

What Is Done in This Major Version of Spring Boot 3.0 and How to Prepare for the Changes?

Spring Boot 3.0 will use Spring Framework 6. In this article, we'll discuss the changes listed from the M1 to M5 milestones.

Minimum supported versions for Spring Boot 3.0 are: 

  • Java 17 along with Spring Framework 6
  • Jakarta EE 9 
  • Gradle 7.3 (7.5 for 3.0.0-M4)
  • Kotlin 1.6 (1.7 for 3.0.0-M4)

Therefore, be mindful when migrating to this Spring Boot version of the framework to avoid breaking your application. Previous Spring Boot versions work well with Java 17, so it's good to start early with the migration of your projects to this version of Java. You can read here what was new in Java 17. 

If you are using an older version of Spring Boot 2.x, please do not migrate straight to 3.0. Instead, migrate to Spring Boot 2.7 and then, following the migration guides, continue to 3.0.

All the deprecations from the previous version are removed in this release. When migrating to this new version, it is recommended to check your code for the usage of deprecated classes.

Jakarta EE 9

This is the first version of the framework to use the Jakarta EE 9 APIs (jakarta.*) and not EE 8 (javax.*).

Because of the update of Jakarta EE to version 9, there are still some third-party libraries/modules that cannot follow up with this change yet (from M1 to M5), leading to temporarily removing their support until they eventually adopt: 

  • SMTP appending with Logback/Log4j 2
  • REST Assured 
  • H2’s web console 
  • Infinispan
  • EhCache 3
  • Jolokia
  • Pooled JMS

Jersey now supports Spring Framework 6 in version 3.0.6. As a result, both the application code and actuator web endpoint support for Jersey have been restored.

The hibernate-micrometer module is now compatible with Jakarta EE 9, thanks to the upgrade to Hibernate 6.1. As a result, Hibernate metrics auto-configuration has been brought back as one of the Spring Boot basics.

Actuator Metrics, Gradle, SAML2 & Flapdoodle Embedded MongoDB, MongoDB Multiple Hosts

Actuator Metrics export properties have been moved; more detailed information can be found here.

Setting the application’s Main Class has been simplified when working with Gradle. bootWar, bootRun, and bootJar resolve the name of the main class by searching it in the source set output files.  

Relying party configuration for SAML2  has a property name change from

spring.security.saml2.relyingparty.registration.{id}.identity-provider

to 

Spring.security.saml2.relyingparty.registration.{id}.asserting-party

Flapdoodle Embedded MongoDB auto-configured dependency management used for a Spring Boot service unit test is no longer supported (see more about JUnit testing here); the library from Flapdoodle project can be used, or, as a better option, a switch can be made to using Testcontainers instead of embedded MongoDB.

Using the spring.data.mongodb.additional-hosts property, now it’s possible for multiple hosts to be configured for MongoDB.

New Logging Date Format, Async Acks (Apache Kafka), No @ConstructingBinding at Type Level & Text-based Banners

Logback and Log4j2 have a new logging date format in order to align with the ISO-8601 standard. The new format is yyyy-MM-dd’T’HH:mm:ss.SSSXXX.

In the old date format, a space character was used to separate the date; the time now in its place is the letter T.

If the old date format pattern needs to be restored then the LOG_DATEFORMAT_PATTERN environment variable can be used, or the property logging.pattern.dateformat.

Async Ack are enabled with Apache Kafka by introducing a new configuration property spring.kafka.listener.async-acks : true, and it’s only applied when there is spring.kafka.listener.async-mode set to manual-immediate or manual.

In @ConfigurationProperties classes, @ConstructorBinding should be deleted because it is no longer required at the type level. It may still be used on a constructor to specify which one should be used for property binding when a class or record has several constructors.

There will no longer be support for image banners, only text-based banner.txt.

Micrometer

Manually bean definitions of JvmInfoMetrics can now be removed since Micrometer's JvmInfoMetrics is auto-configured. An instance of ObservationRegistry from the Micrometer Observation API is now created by Spring Boot. More details can be found here; also, there is an auto-configuration for Micrometer Tracing (Brave, OpenTelemetry, Zipkin) and Micrometer's OtlpMeterRegistry.

Imports for Micrometer binders have been changed from io.micrometer.core.instrument.binder to io.micrometer.binder.

Hibernate 

Because Hibernate 6.1 is used in Spring Boot 3.0 by default, you may need to see the detailed migration guides in order for your application migration to go smoothly. 

The spring-boot-starter-data-jpa and the dependency management for Hibernate dependencies now use the new org.hibernate.orm group ID.

Going back to the old ID generator mapping is no longer supported; therefore, spring.jpa.hibernate.use-new-id-generator-mappings config property is removed.

URL Matching Modifications in WebFlux and Spring MVC

The trailing slash matching configuration option has been deprecated and set to false as of Spring Framework 6.0. As a result, the controller would have previously matched both "GET /hello/world" and "GET /hello/world/":

@RestController
public class HelloWorldController {

  @GetMapping("/hello/world")
  public String sayHello{
    return "Hello";
  } 

}

"GET /hello/world/" is no longer a match by default. This needs to be anticipated before migrating to the new version. There are still ways to configure this by global configuration or adding both routes on the controller handler. 

R2DBC 1.0,  Flyway 9.0, Multiple Batch Jobs, & Spring Session Store Type

Because Spring Boot 3.0 uses R2DBC 1.0 by default, there is no longer a possibility to override the r2dbc-bom.version. For that purpose, many additional attributes and Spring Boot features are now accessible for the separate and individually versioned modules:

  • r2dbc-postgres.version (io.r2dc:r2dbc-postgres)
  • oracle-r2dbc.version (com.oracle.database.r2dbc:oracle-r2dbc)
  • r2dbc-spi.version (io.r2dc:r2dbc-spi)
  • r2dbc-h2.version (io.r2dc:r2dbc-h2)
  • r2dbc-proxy.version (io.r2dc:r2dbc-proxy)
  • r2dbc-pool.version (io.r2dc:r2dbc-pool)

By default, Spring Boot 3.0 uses Flyway 9.0. To find out how this can influence your application, please read the Flyway release notes and blog article.

Multiple batch jobs are not supported anymore for Spring development. When the system starts up, a single job will be run if the auto-configuration recognizes it. If more than one job is identified in the context, then the user must specify a job name to run at startup using the spring.batch.job.name property.

It is no longer possible to explicitly set the store type for a Spring session using spring.session.store-type. If more than one session store repository implementation is found on the classpath, the SessionRepository that should be automatically created is chosen using a defined order. You can create your own SessionRepository bean and stop auto-configuration if Spring Boot's defined ordering doesn't suit your needs.

Clients for Elasticsearch and Templates

The high-level REST client for Elasticsearch support has been removed (as well as Spring Data Elasticsearch templates) in favor of a new auto-configuration Java Elasticsearch client. You can find more details here.

ReactiveElasticsearchClientAutoConfiguration is the new name for RestClientAutoConfiguration, which was formerly located under org.springframework.boot.autoconfigure.data.elasticsearch and now is located at  org.springframework.boot.autoconfigure.elasticsearch.

The brand-new Elasticsearch Java Client now features auto-configuration. It may be set using the current spring.elasticsearch.* configuration parameters. 

ReactiveUserDetailsService & JdkClientHttpConnector Auto-Configuration

In the existence of an AuthenticationManagerResolver, a ReactiveUserDetailsService is no longer automatically set up. Even though there is an AuthenticationManagerResolver, if your application relies on ReactiveUserDetailService, construct your own ReactiveUserDetailsService bean that satisfies its requirements.

A JdkClientHttpConnector will now be automatically configured if Reactor, Jetty's reactive client Netty, and the Apache HTTP client are not present. This enables the usage of WebClient with the JDK's HttpClient.

ANTLR 2, Changes to Cassandra, Redis & Data Properties

Dependency management it's no longer necessary for ANTLR 2 (antlr:antlr). Choose a version of ANTLR 2 that suits your needs if you're using it in your application.

Any properties under the data prefix suggest that Spring Data is necessary on the classpath since the data prefix has been reserved for Spring Data.

Cassandra's configuration properties have been migrated from spring.data.cassandra to  spring.cassandra

As Redis auto-configuration requires Spring Data to be present on the classpath, Configuration Properties for Redis have been relocated from spring.redis to spring.data.redis.

Endpoint Exposure for JMX & Actuator Endpoints Sanitization

To match the default web endpoint exposure, only the health endpoint is now accessible through JMX by default. The management.endpoints.jmx.exposure.include and management.endpoints.jmx.exposure.exclude properties can be configured to change this.

Actuator Endpoints Sanitization

Since sensitive values may be contained in the /env and /configprops endpoints, all values are masked by default. Previously, only keys considered to be sensitive were affected.

The new release and Spring Boot release notes choose a more secure default instead. A role-based method, comparable to the health endpoint details, has replaced the keys-based approach. A property that can take the following values can be used to control whether or not unsanitized values are displayed:

  • NEVER - Every value is sanitized
  • ALWAYS - The output contains all of the values (sanitizing functions will apply).
  • WHEN AUTHORIZED - Values are only present in the output if a user is authorized (sanitizing functions will apply).

Users are always regarded as authorized in JMX. Users are regarded as authorized for HTTP if they have the required roles and have successfully authenticated.

The QuartzEndpoint's sanitization can be configured in a similar manner.

Imports File Generation Auto-Configuration

The contents of the META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports file used to locate auto-configuration classes can now be generated with an annotation processor. Before using this processor, make sure you have deleted any manually created auto-configuration imports files from your project, and then proceed with following the instruction from the Spring Boot documentation about configuring your project's build. If you do not delete the manually created configuration when the annotation processor generates the file, you will encounter this error in the Gradle build:

org.gradle.api.InvalidUserCodeException: Entry META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports is a duplicate but no duplicate handling strategy has been set.

Either delete the manually generated auto-configuration imports files or take the annotation processor out of the build to fix this issue.

Dependency Upgrades 

When it comes to a Spring Boot project, new versions are upgraded for some Spring projects:

Project NameNew Version M1New Version M2New Version M3New Version M4New Version M5
Micrometer2.0.0-M1////
Spring AMQP3.0.0-M13.0.0-M23.0.0-M3//
Spring Batch5.0.0-M15.0.0-M25.0.0-M35.0.0-M4/
Spring Data2022.0.0-M12022.0.0-M32022.0.0-M42022.0.0-M5/
Spring Framework6.0.0-M2//6.0.0-M5/
Spring Integration6.0.0-M16.0.0-M26.0.0-M36.0.0-M4/
Spring HATEOAS2.0.0-M12.0.0-M22.0.0-M32.0.0-M5/
Spring Kafka3.0.0-M13.0.0-M33.0.0-M43.0.0-M5/
Spring LDAP3.0.0-M1////
Spring REST Docs3.0.0-M13.0.0-M23.0.0-M33.0.0-M4/
Spring Security6.0.0-M16.0.0-M2/6.0.0-M36.0.0-M5/6.0.0-M46.0.0-M6/
Spring Session2022.0.0-M1////
Spring Web Services4.0.0-M14.0.0-M2///

Some of the important upgrades of third-party libraries are:

  • Spring  Boot 3.0.0-M1: (Artemis 2.20.0, Hazelcast 5.0, Hibernate Validator 7.0, Jakarta Activation 2.0, Jakarta Annotation 2.0, Jakarta JMS 3.0, Jakarta JSON 2.0, Jakarta JSON Bind 3.0, Jakarta Mail 2.0, Jakarta Persistence 3.0, Jakarta Servlet 5.0, Jakarta Servlet JSP JSTL 2.0, Jakarta Transaction 2.0, Jakarta Validation 3.0, Jakarta WebSocket 2.0, Jakarta WS RS 3.0, Jakarta XML Bind 3.0, Jakarta XML Soap 2.0, Jetty 11, jOOQ 3.16, Tomcat 10)
  • Spring  Boot 3.0.0-M2: (Groovy 4.0, Thymeleaf Layout Dialect 3.1)
  • Spring  Boot 3.0.0-M3: (Flyway 8.5.11, Hibernate 5.6.9.Final, Micrometer 1.10.0-M2, Micrometer Tracing 1.0.0-M5, Netty 4.1.77.Final, Reactor Bom 2022.0.0-M2, Thymeleaf 3.1.0.M2, Tomcat 10.0.21)
  • Spring  Boot 3.0.0-M4: (Flyway 9, Hibernate 6.1,Liquibase 4.13, Lettuce 6.2, Log4j 2.18, Micrometer 1.10.0-M3, Micrometer Tracing 1.0.0-M6, OkHttp 4.10, R2DBC 1.0, Reactor 2022.0.0-M4, Gradle 7.5, Kotlin 1.7)
  • Spring  Boot 3.0.0-M5: (/)

Removed Support and Deprecations 

The support altogether in 3.0 was removed for Apache ActiveMQ , Apache Solr, Atomikos, EhCache 2, and Hazelcast 3. Eclipse Yasson is now a replacement for Apache Johnzon (JSON-B).

Dependency management for RxJava 1.x - 2.x is removed in favor of RxJava 3.

SnakeYAML's JSON parsing was incompatible with the other parser implementations; hence YamlJsonParser was deleted. Switching to one of the other JsonParser implementations is recommended if you have previously been using YamlJsonParser directly.

In Spring Boot 3.0, there are two deprecations:

  • management.prometheus.metrics.export.pushgateway.shutdown-operation push setting is deprecated in favor of post.
  • @AutoConfigureMetrics has been replaced by @AutoConfigureObservability and is deprecated.

How to Proceed

After all the changes that come with the latest Spring Boot version are read and understood, Spring Community recommends preparing your project early on for the upcoming changes and following migration guides for each version. Remember that upgrading gradually is best instead of skipping versions, whether it's about a Spring Boot banking application example or whatever else.

Although it's not recommended for production, you can also try migrating to the Spring Boot 3.0 milestones to know what to expect when migrating your project. Now you know what Spring Boot's latest version is about; all the changes can be found on the official Spring Boot 3.0 Wiki page; please follow for more updates/milestones.

FAQs

Q: What specific Java 17 features are leveraged in Spring Boot 3.0?
Spring Boot 3.0 leverages Java 17 features such as sealed classes for more controlled inheritance, pattern matching for instanceof to simplify conditional extraction, and new APIs like the Foreign Function & Memory API for improved performance and developer productivity.
Q: How to migrate custom configurations from Spring Boot 2.x to 3.0?
To migrate custom configurations from Spring Boot 2.x to 3.0, follow the official migration guide, update dependencies, replace deprecated features with their new equivalents, and test thoroughly to ensure compatibility with Java 17 and Spring Boot 3.0's new configurations and requirements.
Q: What are the implications of the removal of deprecated features for existing applications?
The removal of deprecated features in Spring Boot 3.0 requires applications to replace or update those features with their current alternatives. This may involve refactoring code, updating dependencies, and adopting new practices aligned with Spring Boot 3.0's architecture and Java 17 requirements.
Hristina Nastevska
Hristina Nastevska
Java Engineer

Hristina is a senior software developer specializing in Java. In the last four years, she has been working as a Java backend developer in the banking domain industry. She's a Bachelor of Engineering in applied e-technologies.

Expertise
  • Java
  • Java
  • Spring Boot
  • Microservices
  • AngularJS
  • JavaScript
  • MySQL
  • HTML
  • +3

Ready to start?

Get in touch or schedule a call.