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.
Table of contents
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 Name | New Version M1 | New Version M2 | New Version M3 | New Version M4 | New Version M5 |
Micrometer | 2.0.0-M1 | / | / | / | / |
Spring AMQP | 3.0.0-M1 | 3.0.0-M2 | 3.0.0-M3 | / | / |
Spring Batch | 5.0.0-M1 | 5.0.0-M2 | 5.0.0-M3 | 5.0.0-M4 | / |
Spring Data | 2022.0.0-M1 | 2022.0.0-M3 | 2022.0.0-M4 | 2022.0.0-M5 | / |
Spring Framework | 6.0.0-M2 | / | / | 6.0.0-M5 | / |
Spring Integration | 6.0.0-M1 | 6.0.0-M2 | 6.0.0-M3 | 6.0.0-M4 | / |
Spring HATEOAS | 2.0.0-M1 | 2.0.0-M2 | 2.0.0-M3 | 2.0.0-M5 | / |
Spring Kafka | 3.0.0-M1 | 3.0.0-M3 | 3.0.0-M4 | 3.0.0-M5 | / |
Spring LDAP | 3.0.0-M1 | / | / | / | / |
Spring REST Docs | 3.0.0-M1 | 3.0.0-M2 | 3.0.0-M3 | 3.0.0-M4 | / |
Spring Security | 6.0.0-M1 | 6.0.0-M2/6.0.0-M3 | 6.0.0-M5/6.0.0-M4 | 6.0.0-M6 | / |
Spring Session | 2022.0.0-M1 | / | / | / | / |
Spring Web Services | 4.0.0-M1 | 4.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.