Spring Boot 4.2: novedades y qué rompe al actualizar

Spring Boot 4.2 es una versión menor que no conviene actualizar a ciegas. Trae Spring Framework 7.1, soporte de AMQP 1.0, el método HTTP QUERY y un arranque algo mejor en el jar ejecutable, pero también cambia en silencio las redirecciones de Tomcat, las cabeceras de proxy y el significado de un starter que usa medio mundo. He ejecutado la misma aplicación en 4.1.2 y en la 4.2.0-RC2, la última versión candidata antes de la final, para ver qué cambia de verdad.
Las notas de versión cuentan lo que entra. Lo que no cuentan es qué parte de eso te va a llegar sin avisar: un Location distinto, una cabecera que deja de leerse, un campo que desaparece del JSON de error. Nada de eso falla en la compilación, y buena parte tampoco falla en las pruebas.
Si lo que buscas es la comparativa entre Spring Boot 3 y 4 o la tabla de versiones y soporte, está en mi guía de Spring Boot 4 frente a 3. Aquí solo hablo de lo que cambia al pasar de 4.1 a 4.2.
Spring Boot 4.2 de un vistazo
| Spring Boot 4.2 | |
|---|---|
| Publicación | prevista el 19 de noviembre de 2026 (RC2 del 5 de noviembre) |
| Spring Framework | 7.1 (4.1 usa 7.0) |
| Java | mínimo 17, compatible hasta 27 |
| Servidores embebidos | Tomcat 11.0, Jetty 12.1 |
| Jackson / Hibernate | Jackson 3.1, Hibernate 7.4 |
| Compilación | Maven 3.6.3+, Gradle 8.14+ y 9.x |
| Soporte gratuito hasta | diciembre de 2027 |
| Soporte comercial hasta | diciembre de 2028 |
Las novedades que me parecen importantes, por este orden:
spring-boot-starter-amqpcambia de significado: ahora es AMQP 1.0 y tuRabbitTemplatedeja de compilar.RestTemplatequeda marcado para su eliminación, y con élRestTemplateBuilderyTestRestTemplate.- Las redirecciones de Tomcat pasan a ser relativas por defecto.
- La estrategia
frameworkde cabeceras de proxy deja de leerX-Forwarded-PrefixyForwardedsi no se lo pides. - HTTP QUERY y Problem Details para las excepciones no controladas, las dos novedades de Framework 7.1 que más útiles me parecen.
- Convenciones de OpenTelemetry, configuración OTLP común y SBOM desde el propio jar.
- Arranque con menos CPU en el jar ejecutable, y sin cambios si ya lo extraes.
Qué he probado y cómo
Todo lo que sigue está ejecutado contra Spring Boot 4.2.0-RC2 y 4.1.2, con Java 25, Maven 3.9 y RabbitMQ 4.4 en Docker. La aplicación es un servicio de pedidos pequeño con MVC, Actuator, JPA sobre H2 y clientes HTTP. Lo ejecuté una vez y lo repetí entero al día siguiente, en una sesión aparte, para descartar que algo dependiera de cómo lo había preparado. Cuando salga la versión final lo volveré a ejecutar y actualizaré aquí lo que cambie.
Las salidas que verás son las reales. Lo que no he podido ejecutar lo digo expresamente. Las funciones que no existen en 4.1, como QUERY o los placeholders en @DefaultValue, solo las he ejecutado en 4.2.
AMQP 1.0, y la trampa del starter
La novedad grande de 4.2 es el soporte de AMQP 1.0, el protocolo estándar que hablan ActiveMQ, Azure Service Bus y, desde la versión 4, RabbitMQ de forma nativa. Hasta ahora, en Spring Boot AMQP significaba en la práctica RabbitMQ con el protocolo 0.9.1.
Ahora hay tres opciones, y el nombre de la que usabas ya no significa lo mismo:
| Starter | Protocolo | Para qué | API |
|---|---|---|---|
spring-boot-starter-amqp | AMQP 1.0 genérico (Qpid ProtonJ2) | Portabilidad entre brokers | AmqpClient, @AmqpListener |
spring-boot-starter-amqp-rabbitmq | AMQP 1.0 con cliente de RabbitMQ | Solo RabbitMQ, protocolo nuevo | RabbitAmqpTemplate, @RabbitListener |
spring-boot-starter-rabbitmq | AMQP 0.9.1 | Lo de siempre, incluidos Streams | RabbitTemplate, @RabbitListener |
Esto es lo que pasa si subes de versión sin mirar. Con 4.1.2, este código compila. Con 4.2, el mismo código y el mismo pom.xml:
Notificador.java:[3,44] package org.springframework.amqp.rabbit.core does not exist
Notificador.java:[9,23] cannot find symbol
Al menos es un fallo ruidoso. El arreglo es una línea: cambiar spring-boot-starter-amqp por spring-boot-starter-rabbitmq. Lo he comprobado y compila sin tocar el código.
Cuidado también con las propiedades, porque hay tres prefijos: spring.rabbitmq.* sigue siendo el de AMQP 0.9.1, spring.amqp.* es el del cliente genérico de AMQP 1.0 y spring.amqp.rabbitmq.* el del cliente de RabbitMQ para AMQP 1.0. Este último no da por defecto el usuario guest: si no pones credenciales, se conecta de forma anónima. Y su indicador de salud se llama amqprabbit, no rabbit, así que revisa los grupos de salud que lo incluyan.
Para empezar con AMQP 1.0, esto envía y recibe contra RabbitMQ con el starter genérico:
@Bean
ApplicationRunner enviar(AmqpClient cliente) {
return args -> cliente.to("/queues/pedidos")
.body("pedido 42")
.send()
.get(5, TimeUnit.SECONDS);
}
@Component
static class Receptor {
@AmqpListener(addresses = "/queues/pedidos")
void procesar(String contenido) {
System.out.println("Pedido recibido por AMQP 1.0: " + contenido);
}
}
spring.amqp.host=localhost
spring.amqp.port=5672
spring.amqp.username=guest
spring.amqp.password=guest
Contra RabbitMQ 4.4 en Docker, la salida es la esperada:
Pedido recibido por AMQP 1.0: pedido 42
Un detalle que conviene saber: la cola tiene que existir. Si no está declarada, la aplicación no arranca:
AmqpResourceNotAvailableException: no queue 'pedidos' in vhost '/' [condition = amqp:not-found]
Con 0.9.1 estás acostumbrado a que RabbitAdmin declare las colas a partir de tus beans. En esta prueba, con el cliente genérico, la creé yo antes en el broker.
Mi recomendación: en una aplicación existente, cambia a spring-boot-starter-rabbitmq y no migres de protocolo en la misma subida. AMQP 1.0 tiene sentido si necesitas hablar con más de un broker o vas a empezar algo nuevo; la documentación oficial sigue señalando el 0.9.1 como la integración más completa, incluido el soporte de Streams.
RestTemplate, marcado para su eliminación
Spring Framework 7.1 marca RestTemplate como obsoleto para su eliminación, que se hará en Spring Framework 8.0, todavía sin fecha. Spring Boot 4.2 hace lo mismo con su infraestructura: RestTemplateBuilder, RestTemplateCustomizer y la autoconfiguración.
Sigue funcionando. Mi cliente con RestTemplateBuilder compila y la aplicación arranca igual en las dos versiones, pero ahora el compilador avisa:
ClienteLegado.java:[10,23] org.springframework.web.client.RestTemplate
in org.springframework.web.client has been deprecated and marked for removal
ClienteLegado.java:[12,23] org.springframework.boot.restclient.RestTemplateBuilder
in org.springframework.boot.restclient has been deprecated and marked for removal
⚠️ Si compilas con -Werror o failOnWarning, aquí se rompe el build. Lo he comprobado con -Dmaven.compiler.failOnWarning=true: el mismo código compila en 4.1.2 y falla en 4.2. Y como es un aviso de eliminación, no uno de obsolescencia normal, javac lo muestra sin que actives -Xlint.
Un detalle que me encontré al probarlo: si todavía usas rootUri() en el builder, ese método ya estaba marcado en 4.1 para desaparecer en 4.3. Su sustituto es baseUri(), y es lo primero que conviene cambiar, porque te rompe el build con -Werror incluso antes de subir a 4.2.
La migración es directa en la mayoría de los casos:
// Antes
ClienteLegado(RestTemplateBuilder builder) {
this.plantilla = builder.baseUri("http://localhost:8080").build();
}
String pedidos() {
return this.plantilla.getForObject("/pedidos", String.class);
}
// Después
ClienteNuevo(RestClient.Builder builder) {
this.cliente = builder.baseUrl("http://localhost:8080").build();
}
String pedidos() {
return this.cliente.get().uri("/pedidos").retrieve().body(String.class);
}
Un RestTemplateCustomizer pasa a ser un RestClientCustomizer, y @RestClientTest con MockRestServiceServer debe configurar un RestClient.Builder.
TestRestTemplate también se va
En las pruebas, el relevo es RestTestClient. Se inyecta con @AutoConfigureRestTestClient y trae aserciones propias. Este test pasa en 4.2 y en 4.1.2:
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureRestTestClient
class PedidoRestTestClientTest {
@Autowired
private RestTestClient cliente;
@Test
void creaYDevuelveElPedido() {
this.cliente.post().uri("/pedidos")
.contentType(MediaType.APPLICATION_JSON)
.body(new PedidoController.NuevoPedido("libro"))
.exchange()
.expectStatus().isOk()
.expectBody().jsonPath("$.producto").isEqualTo("libro");
}
}
Que funcione ya en 4.1 importa: puedes migrar las pruebas antes de subir de versión y quitarle ruido a la actualización.
El arranque, medido
4.2 busca clases y recursos directamente en los jars anidados del jar ejecutable, en lugar de abrir una conexión por cada uno, y ordena más rápido las autoconfiguraciones. Las notas dicen que reduce el tiempo de arranque y la memoria reservada, sin dar cifras.
He arrancado la misma aplicación 20 veces con cada versión, con Java 25, la JVM limitada a 2 procesadores y 512 MB de heap, e invirtiendo en cada ronda qué versión arranca primero, para que ninguna se beneficie siempre de las cachés calientes. Tomo el tiempo que informa Spring al llegar a Started y el tiempo de CPU que lleva consumido el proceso en ese momento. Lo mido en dos formatos: el jar ejecutable (java -jar app.jar) y el jar extraído con -Djarmode=tools extract, que es lo que recomiendo en contenedores.
| Medianas de 20 arranques | 4.1.2 | 4.2 | Diferencia | Rondas con menos CPU en 4.2 |
|---|---|---|---|---|
| Jar ejecutable, tiempo de CPU | 8,82 s | 7,78 s | −12 % | 20 de 20 |
| Jar extraído, tiempo de CPU | 7,29 s | 7,34 s | +0,6 % | 10 de 20 |
Doy el tiempo de CPU y no el de reloj porque el Mac estaba ocupado con otras cosas mientras medía, y el reloj se resiente mucho más de eso. He repetido la prueba en tres tandas, en dos días distintos, y el resultado es el mismo en todas: en el jar ejecutable, entre un 7 y un 12 % menos de CPU para arrancar, y en el extraído, ninguna diferencia.
La lectura es clara y no es la que sugiere el titular. La mejora es real en el jar ejecutable: en esta tanda, 4.2 gastó menos CPU en las 20 rondas, y en las otras dos, en 18 y en 20. Pero en el jar extraído no gana nada, lo cual tiene sentido: la optimización está en leer jars anidados, y al extraer ya no los hay.
Y lo más útil: extraer sigue siendo mejor que cualquier mejora de la versión. La 4.2 con java -jar gasta 7,78 s de CPU y la 4.1.2 extraída, 7,29 s. Si tu imagen ya extrae el jar, como explico en la guía de Dockerfile, no esperes notar nada.
Una aclaración sobre estos números: es una aplicación pequeña, en un Mac con Apple Silicon. Repite la medición con tu aplicación antes de prometer nada; el script está pensado para lanzarlo con tus dos jars.
HTTP QUERY: una búsqueda con cuerpo
Framework 7.1 incorpora QUERY, el método estandarizado en la RFC 10008. Es idempotente y seguro como GET, pero admite cuerpo como POST. Resuelve un problema conocido: las búsquedas con filtros tan complejos que no caben en la URL y que acabamos mandando por POST, perdiendo la semántica.
Aún no hay @QueryMapping, así que se declara con @RequestMapping:
@RequestMapping(method = RequestMethod.QUERY, path = "/pedidos/busqueda",
consumes = MediaType.APPLICATION_JSON_VALUE)
List<Pedido> buscar(@RequestBody Filtro filtro) {
return this.repositorio.findByProductoContaining(filtro.texto());
}
$ curl -X QUERY -H 'Content-Type: application/json' \
-d '{"texto":"libro"}' localhost:8080/pedidos/busqueda
[{"producto":"libro de docker","id":1}]
Funciona con Tomcat sin configurar nada. Ahora bien, una petición QUERY tiene que atravesar todo lo que haya delante: balanceador, WAF, API gateway, CORS y cachés. Es un método nuevo y conviene probarlo en tu infraestructura antes de diseñar una API pública alrededor. No lo he probado detrás de ninguno de esos componentes.
Problem Details para las excepciones no controladas
Hasta ahora, una excepción que no controlaba ningún @ExceptionHandler en un @RestController devolvía el JSON de error de Spring Boot. Con Framework 7.1 puedes convertirla en un application/problem+json (RFC 9457) sin escribir un @ControllerAdvice. Es para Spring MVC y depende de la negociación de contenido, así que un navegador que pide HTML puede seguir recibiendo la página de error:
@Configuration(proxyBeanMethods = false)
class ErroresConfig implements WebMvcConfigurer {
@Override
public void configureProblemDetails(ProblemDetailsConfigurer configurer) {
configurer.renderUnhandledExceptions(true);
}
}
La misma excepción, con el mensaje detalle interno que no debe salir, antes y después:
4.1.2 Content-Type: application/json
{"timestamp":"2026-11-05T16:45:46.136Z","status":500,
"error":"Internal Server Error","path":"/pedidos/fallo"}
4.2 Content-Type: application/problem+json
{"status":500,"title":"Internal Server Error"}
El mensaje de la excepción no se expone, que es lo correcto. Si tus clientes leen timestamp o path, esto es opcional precisamente por eso.
Y un cambio que sí te llega sin pedirlo: ProblemDetail ya no rellena instance solo. El mismo 404 de mi aplicación, que sale de un @ExceptionHandler propio. En 4.2 lo he comprobado también sin la configuración anterior, para asegurarme de que el cambio es de la versión:
4.1.2 {"detail":"No existe el pedido 99","instance":"/pedidos/99","status":404,"title":"Not Found"}
4.2 {"detail":"No existe el pedido 99","status":404,"title":"Not Found"}
Framework 7.1 deja de poner ahí la ruta de la petición. Tiene su lógica: la RFC pensó instance para identificar una ocurrencia concreta del problema, y la ruta /pedidos/99 es la misma para todos los que la piden. Si tu frontend o tus logs lo usaban, tendrás que rellenarlo a mano, mejor con un identificador propio que con la ruta.
Observabilidad: más OpenTelemetry
Tres cambios útiles si envías telemetría a un backend OTLP.
Convenciones semánticas de OpenTelemetry. Con una propiedad, las métricas siguen los nombres estables de OTel:
management.observations.conventions=open-telemetry
Por defecto: http.server.requests
Con la propiedad: http.server.request.duration
⚠️ Cambiar el nombre de una métrica rompe los paneles y alertas que la usan, y las notas avisan de que propiedades como management.observations.http.server.requests.name dejan de tener efecto. Actívalo con un plan para tus paneles, no de paso.
Un solo sitio para OTLP. Antes, el endpoint se repetía para trazas, métricas y logs. Ahora hay una configuración común, y cada señal puede seguir sobrescribiéndola:
management.opentelemetry.otlp.endpoint=http://collector:4318
management.opentelemetry.otlp.compression=gzip
Lo he probado con un receptor local, una sola URL base y una cabecera común. Las métricas y las trazas llegan a su ruta, con el gzip y la cabecera:
/v1/metrics gzip pre
/v1/traces gzip pre
Claves de MDC configurables, con management.tracing.mdc.trace-id-key y span-id-key, para que los logs encajen con lo que espera tu plataforma.
Y un cambio silencioso: el LongTaskTimer de las observaciones activas ya no se crea por defecto. En mi aplicación, http.server.requests.active desaparece de /actuator/metrics al subir a 4.2. Si tienes un panel de peticiones en curso, recupéralo con management.metrics.observations.include-active-long-task-timer=true, que he comprobado que lo devuelve. En el mismo cambio desaparece la propiedad management.metrics.observations.ignored-meters: si la usabas para descartar métricas, deja de aplicarse.
SBOM e imágenes: lo que cambia en la cadena de entrega
Con el modo tools, el SBOM ya se puede leer directamente del jar, sin arrancar la aplicación ni exponer Actuator:
$ java -Djarmode=tools -jar app.jar sbom --destination sbom.json
La salida por consola, sin --destination, empieza así en mi aplicación:
{
"bomFormat" : "CycloneDX",
"specVersion" : "1.6",
En 4.1.2, el mismo comando responde Unknown command "sbom". Hace falta que el jar lleve el SBOM dentro, es decir, tener declarado cyclonedx-maven-plugin en el pom.xml. Es cómodo para pasar un escáner de vulnerabilidades en la integración continua sobre el artefacto real.
Si construyes con buildpacks, el builder por defecto pasa a paketobuildpacks/ubuntu-resolute-builder y las imágenes se basan en Ubuntu 26.04 en vez de 24.04. La imagen de ejecución deja de estar fijada a una versión, así que para builds reproducibles hay que fijar builder y runImage. También se puede publicar la caché de build en un registro. Esto no lo he ejecutado: lo cuento desde las notas de versión. Si usas un Dockerfile, no te afecta; tengo una guía de Dockerfile para Spring Boot con cada paso medido.
Mejoras pequeñas que se agradecen
@DefaultValue admite placeholders. En un record de configuración ya se pueden componer valores por defecto:
@ConfigurationProperties("almacen")
public record AlmacenProperties(
@DefaultValue("${spring.application.name}-almacen") String nombre,
@DefaultValue("${almacen.base:/var/datos}/entrada") String ruta) {
}
{"nombre":"demo-boot42-almacen","ruta":"/var/datos/entrada"}
Otras que merece la pena conocer, sacadas de las notas de versión y sin ejecutar:
- Caffeine asíncrona con
spring.cache.caffeine.cache-mode=async. TomcatServerCustomizerpara personalizar elServerde Tomcat.spring.kafka.template.adminyspring.kafka.listener.admin, para unKafkaAdmindedicado.- LDAP con SSL bundles, tanto en el cliente como en el servidor embebido.
- Rutas de salud con varios segmentos en las rutas adicionales de Actuator.
Lo que rompe al subir de 4.1 a 4.2
Esta es la parte que me llevaría impresa a la actualización. Las tres primeras filas no fallan al compilar ni al arrancar y las he comprobado ejecutando las dos versiones.
| Cambio | Síntoma | Solución |
|---|---|---|
| Redirecciones relativas en Tomcat | Location: /pedidos en vez de la URL absoluta | server.tomcat.servlet.use-relative-redirects=false |
framework ignora X-Forwarded-Prefix | URLs generadas sin el prefijo público | spring.mvc.forwarded-headers.use-forwarded-prefix=true |
framework solo lee X-Forwarded-* | Con Forwarded, URLs con el host interno | spring.mvc.forwarded-headers.header-format=standard |
ProblemDetail ya no recibe la ruta como instance | Falta ese campo en las respuestas Problem Details | Asignar un identificador propio si tu contrato lo usa |
spring-boot-starter-amqp es AMQP 1.0 | RabbitTemplate no compila | spring-boot-starter-rabbitmq |
Sin LongTaskTimer activo | Desaparece http.server.requests.active | include-active-long-task-timer=true |
Se elimina management.metrics.observations.ignored-meters | La exclusión de métricas deja de aplicarse | Revisar qué métricas excluías |
| Propiedades de Tomcat movidas | Aviso de propiedad obsoleta | Pasar a server.tomcat.servlet.* |
| Se elimina lo obsoleto en 4.1 | Fallos de compilación | Quitar los avisos antes de subir |
SSL bundle con ciphers o enabled-protocols en gRPC, LDAP u OTLP | La aplicación no arranca | Quitar esas opciones o usar otro bundle |
| Base de datos de Redis en master/replica | Lee y escribe en otra base, no en la 0 | Quitar la propiedad o ponerla a 0 |
| LDAP embebido | Exige un SSL bundle si activas SSL, y su cliente ignora spring.ldap.urls, usuario y contraseña | spring.ldap.embedded.* |
WebFlux con native o framework | Ignora X-Forwarded-Prefix | server.netty.forwarded-headers.use-forwarded-prefix=true (native) o spring.webflux.forwarded-headers.use-forwarded-prefix=true (framework) |
| Janino sin gestión de versión | Dependencia sin versión | Declarar la versión |
Redirecciones relativas
server.tomcat.servlet.use-relative-redirects pasa a true, para alinearse con Tomcat. Este es el sendRedirect("/pedidos") en las dos versiones:
4.1.2 Location: http://localhost:18041/pedidos
4.2 Location: /pedidos
En un navegador da igual, y detrás de un proxy suele ser hasta mejor. El problema está en cualquier cliente o test que compare el Location entero. La propiedad antigua, server.tomcat.use-relative-redirects, sigue funcionando en 4.2, pero está obsoleta: lo he comprobado poniéndola a false.
Cabeceras de proxy
Si usas server.forward-headers-strategy=framework, en 4.2 hay que elegir formato, y por defecto es X-Forwarded-*. Esta es la URL que ve la aplicación al recibir Forwarded: host=f.ejemplo.com;proto=https:
4.1.2 https://f.ejemplo.com/pedidos/url
4.2 http://localhost:18042/pedidos/url
Se arregla con spring.mvc.forwarded-headers.header-format=standard, que he comprobado que vuelve a dar https://f.ejemplo.com/pedidos/url. Pocos proxies usan Forwarded, así que esto afecta a poca gente.
Lo que me preocupa es X-Forwarded-Prefix, mucho más habitual cuando un ingress o un gateway publica la aplicación bajo una ruta. Las notas de la RC2 avisan de que deja de usarse con WebFlux. En mis pruebas con Spring MVC y esta estrategia pasa lo mismo:
Petición con X-Forwarded-Host: x.ejemplo.com y X-Forwarded-Prefix: /api
4.1.2 http://x.ejemplo.com/api/pedidos/url
4.2 http://x.ejemplo.com/pedidos/url
Se recupera con una propiedad, también comprobada:
spring.mvc.forwarded-headers.use-forwarded-prefix=true
Es el cambio que más me preocupa de toda la versión. No da error y puede pasar todas las pruebas, porque casi nadie prueba con un proxy delante, y acaba en enlaces y redirecciones sin el prefijo. Además, la estrategia framework ya solo se aplica a Spring MVC y WebFlux, no a cualquier aplicación servlet.
Cómo actualizar de Spring Boot 4.1 a 4.2
Este es el orden que seguiría:
- Sube primero al último parche de 4.1 y elimina todos los avisos de obsoleto: lo que estaba obsoleto en 4.1 ya no existe en 4.2.
- Migra las pruebas a
RestTestClienten 4.1, donde ya funciona. - Revisa el starter de AMQP y cámbialo a
spring-boot-starter-rabbitmqen el mismo commit de la subida. - Añade el migrador de propiedades y haz que falle el arranque:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-properties-migrator</artifactId>
<scope>runtime</scope>
</dependency>
spring.properties.migrator.fail=on-warning
Con eso, una propiedad renombrada para el arranque y te dice qué cambiar. Esto es lo que da server.tomcat.use-relative-redirects:
The use of configuration keys that have been renamed was found in the environment:
Property source 'commandLineArgs':
Key: server.tomcat.use-relative-redirects
Replacement: server.tomcat.servlet.use-relative-redirects
java.lang.IllegalStateException: Found configuration keys that need to be migrated
La documentación avisa de que no detecta las propiedades añadidas tarde, por ejemplo con @PropertySource. Úsalo en un entorno de pruebas, no en producción.
- Prueba con el proxy real delante en preproducción: redirecciones, enlaces generados y login, sobre todo si publicas bajo un prefijo.
- Revisa paneles y alertas de métricas:
http.server.requests.activey la etiquetaerror, que en los 5xx traducidos por el framework lleva ahora el nombre de la excepción y nonone. - Quita el migrador al terminar. La documentación lo pide expresamente.
RestTemplate no entra en esta lista a propósito: es un aviso, no un bloqueo. Planifícalo aparte, pero no lo dejes para cuando llegue Framework 8.
¿Hay que actualizar ya?
Depende de dónde vengas:
- Si estás en 4.0: su soporte gratuito acaba en diciembre de 2026. Muévete ya a 4.1, que es la versión final más reciente. Si prefieres hacer el trabajo una sola vez, prepara la subida a 4.2 con los pasos de arriba y hazla cuando salga la versión final, prevista para el 19 de noviembre, pero no lleves una versión candidata a producción.
- Si estás en 4.1: no hay prisa. Tiene soporte gratuito hasta julio de 2027. Yo esperaría al primer parche de 4.2 en producción y aprovecharía estas semanas para los pasos 1 y 2.
- Si empiezas un proyecto: 4.2 en cuanto salga la versión final, con
RestClienty Java 25. Si arrancas antes, empieza en 4.1: el salto a 4.2 es corto si sigues los pasos de arriba. - Si sigues en 3.5: tu problema no es este. Perdió el soporte gratuito en junio de 2026, y el salto a 4 es el que explico en la comparativa de Spring Boot 3 y 4.
Preguntas frecuentes
¿Cuándo sale Spring Boot 4.2?
La versión final de Spring Boot 4.2 está prevista para el 19 de noviembre de 2026, junto con Spring Framework 7.1, según el calendario del proyecto en GitHub. La última publicada es la 4.2.0-RC2, una versión candidata del 5 de noviembre de 2026.
¿Qué novedades trae Spring Boot 4.2?
Spring Boot 4.2 se apoya en Spring Framework 7.1 y añade soporte de AMQP 1.0, el método HTTP QUERY, la opción de devolver como Problem Details las excepciones que no controla ningún @ExceptionHandler, convenciones semánticas de OpenTelemetry, configuración OTLP común, un comando para extraer el SBOM del jar y un arranque más rápido en el jar ejecutable. También marca RestTemplate y TestRestTemplate para su eliminación.
¿Qué versión de Java necesita Spring Boot 4.2?
Java 17 como mínimo, y es compatible hasta Java 27. Para producción, la opción razonable es Java 25, el LTS actual.
¿Spring Boot 4.2 elimina RestTemplate?
No. RestTemplate sigue funcionando en Spring Boot 4.2, pero Spring Framework 7.1 lo marca como obsoleto para su eliminación, que está prevista en Spring Framework 8.0, todavía sin fecha. Spring Boot marca también RestTemplateBuilder y TestRestTemplate. Los reemplazos son RestClient y RestTestClient.
¿Por qué deja de compilar spring-boot-starter-amqp en Spring Boot 4.2?
Porque el starter cambia de significado: en 4.2, spring-boot-starter-amqp es AMQP 1.0 genérico sobre Qpid ProtonJ2 y ya no trae RabbitTemplate. Para seguir con AMQP 0.9.1 hay que cambiarlo por spring-boot-starter-rabbitmq, sin tocar el código.
¿Hasta cuándo tiene soporte Spring Boot 4.2?
Según el calendario oficial de Spring, Spring Boot 4.2 tiene soporte open source hasta diciembre de 2027 y soporte comercial hasta diciembre de 2028. Spring Boot 4.1 tiene soporte gratuito hasta julio de 2027.
Conclusión
Spring Boot 4.2 no es una revolución, pero tampoco la subida de una tarde sin mirar. Lo mejor es lo que abre: AMQP 1.0, QUERY, errores estándar y más opciones de OpenTelemetry. Lo delicado es lo que cambia sin decir nada: redirecciones, cabeceras de proxy y campos que desaparecen.
Mi consejo se resume en una frase: haz los deberes en 4.1 y, cuando salga la versión final, sube con el migrador en modo estricto y prueba con el proxy delante. Los ejemplos de este artículo están pensados para repetirlos en tu aplicación en una hora.
Si quieres ir más allá de las versiones —arquitectura hexagonal, mensajería y observabilidad en aplicaciones reales—, es lo que cubre mi libro Spring Boot Avanzado. Y si tienes una actualización delicada entre manos y prefieres que la revisemos juntos, puedes escribirme.
¿Buscas un consultor IT para tu empresa? Conoce mis servicios de consultoría IT: arquitectura cloud, desarrollo fullstack y liderazgo técnico. ¿Empresa en Mallorca o Baleares? Consultor IT en Mallorca.