Spring Framework is a popular open source enterprise framework for creating standalone, production-grade applications that run on the Java Virtual Machine (JVM). And Spring Boot is a tool that makes it faster and easier to develop web applications and microservices using the Spring framework. As Spring Boot continues to evolve, developers must keep up with the latest upgrades and changes.
Recently, Spring Boot announced the release of version 3.2.x, which brings a number of new features, bug fixes, and enhancements. This is a good news given that support for Spring Boot 2.7.x version has ended on November 18, 2023. Very important and mandatory attention is used to upgrade Spring Boot applications to the latest 3.x version.
Therefore, in this article, we will discuss how to migrate from Spring Boot 2.x to 3.x, as well as the advantages of upgrading and the potential difficulties developers may encounter during the process.
Contents
- 1 Upgrade guide
- 1.1 1. Upgrade JDK 17
- 1.2 2. Upgrade to Spring Boot 3
- 1.3 3. Configuration attribute migration
- 1.4 4. Upgrade to Jakarta EE
- 1.5 5. Adjust @ConstructorBindingannotations
- 1.6 6. URL matching changes for Spring MVC and WebFlux
- 1.7 7. Apache HttpClient in RestTemplate
- 1.8 8. Upgrade Spring Security
- 1.9 9. Spring Kafka template upgrade
- 1.10 10. Spring Doc OpenAPI upgrade
Upgrade guide
1. Upgrade JDK 17
Spring Boot 3.0 requires Java 17 as a minimum version.
If you are currently using Java 8 or Java 11, you need to upgrade your JDK before migrating to Spring Boot.
2. Upgrade to Spring Boot 3
After reviewing the status of the project and its dependencies, upgrade to the latest maintenance release of Spring Boot 3.0.
We will use Spring Boot 3.2.0 for the upgrade.
Open the project’s pom.xmland update the Spring Boot version as shown below.
< parent >
< groupId > org.springframework.boot </ groupId >
< artifactId > spring-boot-starter-parent </ artifactId >
< version > 3.2.0 </ version >
</ parent >
3. Configuration attribute migration
In Spring Boot 3.0, some configuration properties were renamed/removed and developers need to update them accordingly application.properties/application.yml.
To help you achieve this, Spring Boot provides a spring-boot-properties-migratormodule.
pom.xmlWe can add the migrator by adding the following to Maven :
< dependency > < groupId > org.springframework.boot </ groupId > < artifactId > spring-boot-properties-migrator </ artifactId > < scope > runtime </ scope > </ dependency >
4. Upgrade to Jakarta EE
Since Java EE has been changed to Jakarta EE, all dependency APIs of Spring Boot 3.x have also been upgraded from Java EE to Jakarta EE.
Simply put, you need to javaxreplace all imports with jakarta. details as follows:
javax .persistence.* -> jakarta.persistence.* javax .validation.* -> jakarta.validation.* javax .servlet.* -> jakarta.servlet.* javax .annotation.* -> jakarta.annotation.* javax . transaction.* -> jakarta.transaction.*
5. Adjust @ConstructorBindingannotations
@ConstructorBindingIt is no longer needed at @ConfigurationPropertiesthe type level of the class and should be removed.
When a class or record has multiple constructors, it can still be used on the constructor to indicate which constructor should be used for property binding.
6. URL matching changes for Spring MVC and WebFlux
Starting with Spring Framework 6.0, the trailing slash matching configuration option has been deprecated and its default value is set to false.
This means that previously, the following controller would match GET /healthandGET /health/
@RestController
public class HealthController {
@GetMapping("/health")
public String health () {
return "Application is Working" ;
}
}
@RestController
public class HealthController {
@GetMapping("/health")
public Mono<String> health () {
return Mono.just( "Application is Working" );
}
}
7. Apache HttpClient in RestTemplate
Support for Apache HttpClient was removed in Spring Framework 6.0 and is now org.apache.httpcomponents.client5:httpclient5replaced by (note: this dependency has a different groupId).
If you notice problems with HTTP client behavior, you RestTemplatemay fall back to the JDK client.
org.apache.httpcomponents:httpclientCan be transitively passed by other dependencies, so your application may depend on this dependency without declaring it.
Here is an example after migration RestTemplate:
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate () {
final SSLConnectionSocketFactory sslConnectionSocketFactory = SSLConnectionSocketFactoryBuilder.create()
.build();
final PoolingHttpClientConnectionManager manager = PoolingHttpClientConnectionManagerBuilder.create()
.setSSLSocketFactory(sslConnectionSocketFactory)
.build();
final CloseableHttpClient closeableHttpClient = HttpClients.custom().setConnectionManager(manager)
.build();
final HttpComponentsClientHttpRequestFactory componentsClientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory ();
componentsClientHttpRequestFactory.setHttpClient(closeableHttpClient);
final RestTemplate restTemplate = new RestTemplate (componentsClientHttpRequestFactory);
return restTemplate;
}
}
8. Upgrade Spring Security
Spring Boot 3.0 has been upgraded to Spring Security 6.0.
Therefore, WebSecurityConfigurerAdapterit has been deprecated. Spring encourages users to move to component-based security configuration.
To demonstrate the new configuration style, we use the Spring Security lambda DSL and methods HttpSecurity#authorizeHttpRequeststo define our authorization rules.
Here is WebSecurityConfigurerAdapteran example configuration using HTTP Basic, which secures all endpoints:
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure (HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz
.anyRequest().authenticated()
)
.httpBasic(withDefaults());
}
}
Going forward, the recommended approach is to register a SecurityFilterChainbean:
@Configuration
public class SecurityConfiguration {
@Bean
public SecurityFilterChain filterChain (HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz
.anyRequest().authenticated()
)
.httpBasic(withDefaults());
return http.build();
}
}
9. Spring Kafka template upgrade
KafkaTemplateThe method now returns CompleteableFutureinstead ListenableFuture, which has been deprecated.
ListenableFutureKafka template in Spring Boot 2.x with :
private RoutingKafkaTemplate routingKafkaTemplate;
public void send () {
ListenableFuture<SendResult<Object,Object>> future = routingKafkaTemplate.send( "Message" , "topic" );
future.addCallback( new ListenableFutureCallback <>() {
@Override
public void onFailure (Throwable ex) {
log.error(ex);
}
@Override
public void onSuccess (SendResult<Object, Object> result) {
log.info( "success" );
}
});
}
CompletableFutureKafka template in Spring Boot 3.x with :
private RoutingKafkaTemplate routingKafkaTemplate;
public void send () {
CompletableFuture<SendResult<Object, Object>> future = routingKafkaTemplate.send( "Message" , "topic" );
future.thenAccept(log::info)
.exceptionally(exception -> {
log.error(exception);
return null ;
});
}
10. Spring Doc OpenAPI upgrade
springdoc-openapiUsed to automatically generate API documentation for Spring Boot projects.
springdoc-openapiworks by inspecting the application at runtime to infer API semantics based on spring configuration, class structure, and various annotations.
For spring-boot 3 support, make sure to use springdoc-openapi v2.
Spring Doc OpenAPI upgrade of WebMVC project
For WebMVC projects, you need to pom.xmlinclude the following dependencies in the . file.
< dependency >
< groupId > org.springdoc </ groupId >
< artifactId > springdoc-openapi-starter-webmvc-ui </ artifactId >
< version > 2.3.0 </ version >
</ dependency >
Spring Doc OpenAPI upgrade for WebFlux project
For WebFlux projects, you need to pom.xmlinclude the following dependencies in the . file.
< dependency >
< groupId > org.springdoc </ groupId >
< artifactId > springdoc-openapi-starter-webflux-ui </ artifactId >
< version > 2.3.0 </ version >
</ dependency >
