Comprehensive upgrade guide from Spring Boot 2.x to 3.2

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.

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 >