Featured image of post Migração do Spring Boot 3 para 4: Um Guia Estratégico para Preparar sua API para o Futuro

Migração do Spring Boot 3 para 4: Um Guia Estratégico para Preparar sua API para o Futuro

Aprenda o passo a passo para migrar sua aplicação Spring Boot 3 para a versão 4, explorando o suporte nativo para versionamento de APIs, as mudanças do ecossistema Jakarta EE e as práticas recomendadas para uma transição segura e planejada.

Migração do Spring Boot 3 para 4: Um Guia Estratégico para Preparar sua API para o Futuro


Sumário

  1. Visão Geral
  2. Pré-requisitos e Compatibilidade
  3. Principais Mudanças Introduzidas
  4. Fases da Migração
  5. Detalhamento das Quebras de Compatibilidade
  6. Configuração de Propriedades
  7. Segurança (Spring Security 7)
  8. Persistência (Hibernate 7 + Spring Data 2025.1)
  9. Testes
  10. Build e Ferramentas
  11. Conclusão
  12. Referências

1. Visão Geral

O Spring Boot 4.0 foi lançado em novembro de 2025 e representa a maior evolução do framework desde a mudança javax → jakarta introduzida no Spring Boot 3. Esta versão é construída sobre o Spring Framework 7 e o Jakarta EE 11, trazendo modularização completa do autoconfigure, suporte nativo a threads virtuais, versioning de APIs REST e segurança de nulos via JSpecify.

Por que migrar?

Motivo Detalhe
Suporte ao SB 3.5 encerra em nov/2026 Após essa data, sem patches de segurança
Performance Menor uso de memória, startup mais rápido com imagens nativas
Modularidade Mais de 70 starters granulares — reduza CVEs desnecessários
Thread Virtual Suporte nativo ao Project Loom (Java 21+)
Segurança de Nulos JSpecify integrado ao nível de API do framework
LTS até 2030 Menor necessidade de migrações frequentes

Escopo da migração

Esta é uma migração major — espere trabalho real. Não basta simplesmente alterar a versão no pom.xml ou build.gradle. As principais áreas impactadas são:

  • Runtime Java (mínimo Java 17, recomendado Java 21)
  • Build tool (Gradle 8.14+, Maven 3.6.3+)
  • Dependências transitivas (Jackson 3, Hibernate 7, Spring Security 7)
  • Propriedades de configuração renomeadas/removidas
  • APIs deprecadas removidas

2. Pré-requisitos e Compatibilidade

Versões obrigatórias

Componente Versão Mínima Versão Recomendada
Java 17 21 (LTS) ou 25
Spring Framework 7.x 7.x
Jakarta EE 11 11
Servlet 6.1 6.1
Maven 3.6.3 3.9+
Gradle 8.14 9.x
Kotlin 2.2 2.2+
GraalVM native-image 25 25+

Módulos do ecossistema Spring compatíveis com Boot 4

Módulo Versão no Boot 4
Spring Framework 7.0
Spring Security 7.0
Spring Data 2025.1
Spring Batch 6.0
Spring AMQP 4.0
Spring Integration 7.0
Spring for Apache Kafka 4.0
Spring GraphQL 2.0
Spring Session 4.0
Spring WS 5.0
Spring REST Docs 4.0

⚠️ Atenção — Ecossistema de terceiros: Bibliotecas externas (Spring Cloud, starters customizados, integrações proprietárias) podem ainda não ser compatíveis com Spring Boot 4. Audite todas as dependências antes de iniciar a migração.


3. Principais Mudanças Introduzidas

3.1 Modularização completa

O autoconfigure monolítico foi dividido em 70+ módulos focados. Isso reduz o tamanho dos artefatos e elimina dependências transitivas desnecessárias.

3.2 JSpecify e null safety

O Spring Boot 4 incorpora anotações JSpecify (@Nullable, @NonNull) em toda a API do framework, formalizando o contrato de nulos ao nível do compilador.

3.3 Suporte a Java 25 (mantendo Java 17)

Permite uso do Java 25, com retrocompatibilidade garantida para Java 17.

3.4 API Versioning nativo

Suporte built-in para versionamento de APIs REST sem necessidade de bibliotecas externas.

3.5 HTTP Service Clients aprimorados

Melhorias significativas na abstração de clientes HTTP declarativos.

3.6 Virtual Threads (Project Loom)

Suporte nativo para threads virtuais do Java 21, com configuração simplificada e sem necessidade de WebFlux para cargas de trabalho I/O-bound.


4. Fases da Migração

Fase 0 — Preparação

Objetivo: Garantir que a aplicação está no estado ideal em Spring Boot 3.x antes de qualquer upgrade.

1
2
3
4
5
6
7
8
[ ] Atualizar para o Spring Boot 3.5.x mais recente
[ ] Compilar com flag -Xlint:deprecation
[ ] Resolver TODOS os warnings de deprecação
[ ] Mapear dependências de terceiros e verificar compatibilidade com SB4
[ ] Identificar bibliotecas sem release para Spring Framework 7
[ ] Garantir cobertura de testes adequada (unitários + integração)
[ ] Criar branch de migração isolada no repositório
[ ] Configurar pipeline CI dedicado para a branch de migração

Por que isso é crítico?

O Spring Boot 3.5 foi projetado como ponte para o 4.0. Todos os itens deprecados no 3.x que foram removidos no 4.0 já emitem warnings no 3.5. Resolver esses warnings no 3.5 é muito mais seguro do que descobrir as quebras diretamente no 4.0.


Fase 1 — Atualização do Runtime Java

Objetivo: Garantir que a JVM e o toolchain estejam compatíveis.

1
2
3
4
5
6
# Verificar versão atual
java -version

# Instalar Java 21 (recomendado via SDKMAN)
sdk install java 21.0.3-tem
sdk use java 21.0.3-tem

Atualize o pom.xml:

1
2
3
4
5
<properties>
    <java.version>21</java.version>
    <maven.compiler.source>21</maven.compiler.source>
    <maven.compiler.target>21</maven.compiler.target>
</properties>

Atualize o build.gradle:

1
2
3
4
5
java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

Fase 2 — Atualização do Build Tool

Maven — pom.xml:

1
2
3
4
5
6
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>4.0.x</version> <!-- Use a versão mais recente do 4.0 -->
    <relativePath/>
</parent>

Gradle — build.gradle:

1
2
3
4
5
plugins {
    id 'org.springframework.boot' version '4.0.x'
    id 'io.spring.dependency-management' version '1.1.x'
    id 'java'
}

Se usar Gradle, atualize para Gradle 9 (mínimo 8.14).


Fase 3 — Migração de Dependências

Adicionar o migrador de propriedades (temporário):

1
2
3
4
5
6
<!-- Maven -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-properties-migrator</artifactId>
    <scope>runtime</scope>
</dependency>
1
2
// Gradle
runtimeOnly("org.springframework.boot:spring-boot-properties-migrator")

⚠️ Remova essa dependência após concluir a migração de propriedades. Ela tem impacto de performance e não deve ir para produção.

Jackson 3 (breaking change):

O Spring Boot 4 usa Jackson 3, que possui mudanças de pacote. Dependências que importam classes Jackson diretamente precisam de revisão.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<!-- Antes (Jackson 2.x) -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.x.x</version>
</dependency>

<!-- Depois (Jackson 3 — gerenciado pelo Spring Boot 4) -->
<!-- Remova a versão explícita e deixe o BOM gerenciar -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>

Hibernate Processor (breaking change):

1
2
3
4
5
// Antes
annotationProcessor("org.hibernate:hibernate-jpamodelgen")

// Depois
annotationProcessor("org.hibernate.orm:hibernate-processor")

Fase 4 — Refatoração de Código

Veja o Detalhamento das Quebras de Compatibilidade para guia completo por área.

Ordem recomendada:

  1. Resolver erros de compilação (APIs removidas)
  2. Atualizar imports e pacotes renomeados
  3. Ajustar configurações de segurança
  4. Revisar queries JPA/JPQL
  5. Atualizar testes

Fase 5 — Validação e Testes

1
2
3
4
5
6
7
8
[ ] Executar bateria completa de testes unitários
[ ] Executar testes de integração com banco de dados real
[ ] Executar testes de contrato (Pact, Spring Cloud Contract)
[ ] Testes de carga/performance (comparar métricas com SB3)
[ ] Validar endpoints de segurança (autenticação + autorização)
[ ] Validar geração de tokens JWT/OAuth2
[ ] Testar em ambiente de staging idêntico à produção
[ ] Verificar logs de inicialização (sem warnings residuais)

Fase 6 — Deploy em Produção

Se possível fazer uma estratégia de rollback parcial para validar a versão, ótimo! Se não esteja preparado para rollback rápido caso as coisas se comportem mal… Se ainda não tem estratégias de deploy separadas vale conferir como implementar Blue-Green deployment ou Canary release na sua estrutura atual :)


5. Detalhamento das Quebras de Compatibilidade

5.1 Undertow removido

O Spring Boot 4 remove o suporte ao servidor Undertow. Aplicações que usam Undertow devem migrar para Tomcat (padrão) ou Jetty.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- Antes: usando Undertow -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-undertow</artifactId>
</dependency>

<!-- Depois: remova as exclusões e use Tomcat (padrão) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

5.2 JUnit 4 removido

O suporte ao JUnit 4 foi completamente removido. Todos os testes devem usar JUnit 5 (Jupiter).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
// Antes (JUnit 4)
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
public class MeuTesteTest {
    @Test
    public void deveFazerAlgo() { ... }
}

// Depois (JUnit 5)
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class MeuTesteTest {
    @Test
    void deveFazerAlgo() { ... }
}

5.3 Spring Security — Mudança de defaults

O Spring Security 7 alterou comportamentos padrão que podem silenciosamente quebrar APIs REST sem mensagem de erro óbvia.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// Antes (SB3/Security 6) — CSRF desabilitado era comum para APIs REST
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http.csrf().disable()
        .authorizeHttpRequests(auth -> auth.anyRequest().authenticated());
    return http.build();
}

// Depois (SB4/Security 7) — API atualizada, sem métodos deprecados
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .csrf(csrf -> csrf.disable())
        .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
        .sessionManagement(session ->
            session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
    return http.build();
}

5.4 Jackson 3 — Mudanças de comportamento

Jackson 3 (incluído no Spring Boot 4) traz mudanças que podem afetar serialização/deserialização:

  • Comportamento padrão mais restritivo com tipos desconhecidos
  • Mudanças em como null é serializado em coleções
  • Módulos Jackson que importavam classes internas devem ser atualizados
1
2
3
4
5
6
7
8
9
// Verificar: configurações explícitas do ObjectMapper
@Bean
public ObjectMapper objectMapper() {
    return JsonMapper.builder()
        .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
        .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
        .addModule(new JavaTimeModule())
        .build();
}

5.5 Starter renames (módulos renomeados)

Alguns starters foram renomeados na modularização do Boot 4. Consulte a tabela completa de dependências no site oficial.


6. Configuração de Propriedades

Use o spring-boot-properties-migrator para identificar propriedades alteradas automaticamente. Além disso, revise manualmente as configurações críticas.

Como usar o migrator

  1. Adicione a dependência conforme Fase 3
  2. Inicie a aplicação — o migrator imprime no log:
    • Propriedades que foram renomeadas (migra em runtime automaticamente)
    • Propriedades que foram removidas (você precisa agir manualmente)
  3. Corrija as propriedades no application.properties / application.yml
  4. Remova a dependência do migrator

7. Segurança (Spring Security 7)

7.1 OIDC e OAuth2

O Spring Security 7 atualiza a conformidade OIDC. Se sua aplicação usa autenticação OAuth2/OIDC, revise:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// Configuração de Resource Server (JWT)
@Bean
public SecurityFilterChain resourceServerFilterChain(HttpSecurity http) throws Exception {
    http
        .authorizeHttpRequests(auth -> auth
            .requestMatchers("/public/**").permitAll()
            .anyRequest().authenticated()
        )
        .oauth2ResourceServer(oauth2 -> oauth2
            .jwt(jwt -> jwt.decoder(jwtDecoder()))
        );
    return http.build();
}

7.2 CORS

Revise configurações de CORS — os defaults podem ter mudado:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
@Bean
public CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowedOrigins(List.of("https://meudominio.com"));
    config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE"));
    config.setAllowedHeaders(List.of("*"));
    
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", config);
    return source;
}

8. Persistência (Hibernate 7 + Spring Data 2025.1)

8.1 Hibernate 7 — Principais mudanças

O Hibernate 7.1 traz melhorias significativas de performance e compatibilidade com threads virtuais (usa ReentrantLock em vez de blocos synchronized).

Semantic Query Model (SQM): O Hibernate 7 otimiza queries automaticamente via SQM. Queries HQL/JPQL existentes devem funcionar, mas edge cases com queries nativas complexas devem ser testados.

Processor renomeado:

1
2
3
4
5
6
// build.gradle
// Antes
annotationProcessor 'org.hibernate:hibernate-jpamodelgen'

// Depois
annotationProcessor 'org.hibernate.orm:hibernate-processor'

8.2 Spring Data 2025.1

O Spring Data 2025.1 muda a geração de queries derivadas:

1
2
3
4
5
6
7
8
// Queries derivadas agora geram JPQL como string em build-time
// (antes usavam Criteria API em runtime)
// Isso melhora startup e compatibilidade com GraalVM

// Comportamento deve ser transparente, mas teste queries complexas:
interface UserRepository extends JpaRepository<User, Long> {
    List<User> findByNomeAndStatusOrderByCreatedAtDesc(String nome, Status status);
}

Processamento de queries em build-time:

A partir do Spring Data 2025.1, queries são processadas em compile time por padrão. Isso melhora startup e GraalVM native, mas pode revelar erros de JPQL que antes só apareciam em runtime.


9. Testes

9.1 Remoção do JUnit 4

Busque e substitua anotações JUnit 4 no projeto inteiro:

1
2
# Buscar usos de JUnit 4 no projeto
grep -r "org.junit.Test\|@RunWith\|SpringRunner\|JUnit4" src/test/

9.2 @MockBean e @SpyBean

Verifique se mudanças no contexto de teste afetam o comportamento de mocks:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// JUnit 5 + Mockito moderno
@ExtendWith(MockitoExtension.class)
class ServicoTest {
    @Mock
    private RepositorioUsuario repositorio;
    
    @InjectMocks
    private ServicoUsuario servico;
    
    @Test
    void deveRetornarUsuario() {
        // ...
    }
}

9.3 Testcontainers (recomendado para integração)

O Spring Boot 4 aprimora a integração com Testcontainers:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
@SpringBootTest
@Testcontainers
class IntegracaoTest {
    @Container
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16");
    
    @DynamicPropertySource
    static void configureProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.datasource.url", postgres::getJdbcUrl);
        registry.add("spring.datasource.username", postgres::getUsername);
        registry.add("spring.datasource.password", postgres::getPassword);
    }
}

10. Build e Ferramentas

10.1 Gradle 9

Se migrar para Gradle 9, atente para:

  • APIs do Gradle que foram removidas no 9.x
  • compile e runtime configurations removidas (use implementation/runtimeOnly)
  • Verificação de dependências mais rigorosa
1
2
# Verificar problemas de compatibilidade com Gradle 9
./gradlew help --warning-mode all

10.2 GraalVM Native Image

Para imagens nativas, atualize para GraalVM 25:

1
2
3
4
5
6
7
8
# Com SDKMAN
sdk install java 25.0.0-graal
sdk use java 25.0.0-graal

# Build nativo
./mvnw -Pnative native:compile
# ou
./gradlew nativeCompile

10.3 Spring Boot 4.1?

O Spring Boot 4.1 já está disponível, com melhorias reativas e maior modularização do GraalVM. Mantenha o roadmap em vista ao planejar upgrades futuros.


11. Conclusão

A migração do Spring Boot 3 para o 4 não é apenas uma atualização técnica — é um passo estratégico para alinhar o projeto às práticas modernas de desenvolvimento.

Com suporte nativo para versionamento de APIs, melhorias de desempenho e maior integração com o ecossistema Jakarta EE, a versão 4 simplifica a manutenção e prepara o caminho para arquiteturas mais resilientes e escaláveis.

Planejar cada etapa, testar incrementalmente e documentar as mudanças são os pilares para uma transição suave. Ao final, o esforço de migração se traduz em um código mais limpo, seguro e preparado para o futuro.

Obrigado por chegar até aqui


12. Referências

comments powered by Disqus
Criado com Hugo
Tema Stack desenvolvido por Jimmy