Molti sistemi enterprise girano ancora su Spring Boot 2.7 o 3.x. I team sanno che l'aggiornamento è necessario, ma perde sempre contro le funzionalità richieste dal business. Ora decide il calendario: il supporto open source di Spring Boot 3.5 è terminato il 30 giugno 2026 e quello della 4.0 termina il 31 dicembre 2026. In questo articolo descriviamo come aggiorniamo applicazioni Spring di grandi dimensioni senza fermare lo sviluppo. Versioni e date sono aggiornate a ottobre 2026 e provengono da spring.io e dalle guide di migrazione ufficiali.
A che punto sono le date di supporto
Dal calendario di supporto di Spring Boot:
| Linea | Supporto open source fino al | Supporto commerciale fino al |
|---|---|---|
| 2.7.x | 30 giugno 2023 (terminato) | 30 giugno 2029 |
| 3.4.x | 31 dicembre 2025 (terminato) | 31 dicembre 2026 |
| 3.5.x | 30 giugno 2026 (terminato) | 30 giugno 2032 |
| 4.0.x | 31 dicembre 2026 | 31 dicembre 2027 |
| 4.1.x | 31 luglio 2027 | 31 luglio 2028 |
La support policy di Spring garantisce a ogni minor release almeno 13 mesi di supporto e all'ultima minor di ogni linea principale (2.7, 3.5) altri cinque anni di supporto enterprise. Il supporto commerciale fa guadagnare tempo, ma non elimina il lavoro, e le librerie attorno a Spring continuano comunque a evolversi. Come destinazione vi consigliamo Spring Boot 4.1 (4.1.1 nel momento in cui scriviamo): la 4.0 esce dal supporto open source fra meno di tre mesi.
Il percorso incrementale
Le guide ufficiali sono chiare: prima di passare alla 3.0 si aggiorna all'ultima 2.7.x, prima della 4.0 all'ultima 3.5.x. Ciò che è deprecato in una linea viene rimosso nella major successiva, quindi eliminare i warning di deprecazione fa parte dell'upgrade, non è pulizia da rimandare.
- Su 2.7, prima Java. Spring Boot 2.7.18 richiede Java 8 ed è compatibile fino a Java 21. Passare a Java 17 o 21 restando sulla versione attuale di Boot separa i problemi della JVM da quelli del framework. Portate anche Spring Security alla 5.8, come raccomanda la guida della 3.0.
- Da 2.7 a 3.5. La vera rottura avviene con la 3.0: Java 17 come minimo, Jakarta EE 10, Hibernate 6, Spring Security 6. Da lì si risale alle minor successive fino alla 3.5, leggendo ogni release note. Spring Boot 3.5.16 è compatibile con Java da 17 a 25.
- Da 3.5 a 4.1. Spring Framework 7, Jakarta EE 11 con Servlet 6.1, Hibernate 7, Jackson 3, starter modulari. Spring Boot 4.1.1 richiede Java 17 ed è compatibile fino a Java 26. Di solito puntiamo a Java 21 o a Java 25, quest'ultimo disponibile in GA dal 16 settembre 2025.
A ogni passo aggiungete temporaneamente spring-boot-properties-migrator: all'avvio segnala le proprietà rinominate o rimosse e le rimappa a runtime. Va tolto quando i warning sono spariti.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-properties-migrator</artifactId>
<scope>runtime</scope>
</dependency>
Jakarta EE e gli altri breaking change
Con Boot 3 i package passano da javax.* a jakarta.*. Gli import sono la parte facile; quella difficile sono le librerie che pubblicano solo artefatti javax, spesso transitive: cercate nell'albero delle dipendenze javax.servlet, javax.persistence e javax.validation e trattate ogni occorrenza come una libreria da aggiornare, sostituire o isolare. Attenzione anche ai cambiamenti che compilano ma si comportano diversamente, come il trailing-slash matching, disattivato di default dalla 3.0: GET /orders/ non corrisponde più a /orders.
Boot 4 porta la sua lista. I punti che di solito richiedono più tempo:
- Jackson 3: i package passano da
com.fasterxml.jacksonatools.jackson(le annotazioni mantengono il nome) e i customizer cambiano nome. Jackson 2 resta disponibile come ponte con il modulo deprecatospring-boot-jackson2. - Starter modulari:
spring-boot-starter-webdiventaspring-boot-starter-webmvc, Flyway e Liquibase richiedono starter dedicati.spring-boot-starter-classicè una soluzione transitoria. - Funzionalità rimosse: Undertow è stato eliminato, perché non è ancora compatibile con Servlet 6.1.
- Test:
@MockBeane@SpyBeansono sostituiti da@MockitoBeane@MockitoSpyBean, e@SpringBootTestnon configura più MockMvc senza@AutoConfigureMockMvc.
Hibernate 6 e 7: cosa verificare
I cambiamenti di Hibernate raramente rompono la build: cambiano l'SQL generato e il rapporto con lo schema. Spring Boot 3.0 è passato a Hibernate 6.1, Boot 4.0 a Hibernate 7.2 con Jakarta Persistence 3.2, e Boot 4.1 include Hibernate 7.4. Dalle guide di migrazione ufficiali, meritano attenzione:
Sequence (6.0): i generatori impliciti usano una sequence per entità (
<entity>_seq) invece dihibernate_sequence, con allocation size 50. Gli schemi esistenti richiedono nuove sequence, oppure un'impostazione di compatibilità mentre pianificate la modifica:spring.jpa.properties.hibernate.id.db_structure_naming_strategy=legacyTipi:
Instant, gli UUID su MariaDB e SQL Server e la memorizzazione dei fusi orari sono mappati diversamente. Eseguite la validazione dello schema su una copia della produzione.Fetching (6.0): la natura lazy delle associazioni mappate con
FetchMode.JOINè ora rispettata anche quando si carica un'entità per id. Aspettatevi eccezioni di lazy loading o query aggiuntive.API rimosse (7.0):
Session#save,update,saveOrUpdate,deleteeloadlasciano il posto apersist,merge,removeegetReference.Validazione più severa (7.0): le annotazioni di mapping in posizione errata, prima ignorate, ora generano errori.
Per i casi d'uso critici confrontiamo l'SQL generato prima e dopo e contiamo le query nei test, per far emergere le regressioni N+1 prima della produzione.
OpenRewrite: un acceleratore, non una garanzia
OpenRewrite automatizza le modifiche meccaniche: import, tipi rinominati, proprietà, versioni delle dipendenze. Le ricette rilevanti includono UpgradeSpringBoot_3_5 e UpgradeSpringBoot_4_0 in rewrite-spring, JavaxMigrationToJakarta e UpgradeToJava25 in rewrite-migrate-java. Partite da un dry run e revisionate la patch come qualsiasi altra modifica:
mvn -U org.openrewrite.maven:rewrite-maven-plugin:dryRun \
-Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-spring:RELEASE \
-Drewrite.activeRecipes=org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_5
Tre avvertenze. Leggete cosa contiene una ricetta: quella community per Spring Boot 4.0 copre Spring Framework 7, Spring Security 7, Hibernate 7.1, Testcontainers 2 e i nuovi nomi degli starter, ma non una migrazione completa del vostro codice a Jackson 3. Le ricette cambiano la sintassi, non la semantica: non si accorgono che una query ora restituisce righe diverse. Infine verificate la licenza: il framework e i plugin di build sono Apache 2.0, ma molte ricette Spring e di migrazione sono sotto Moderne Source Available License, che limita alcuni usi commerciali, e gli artefatti delle ricette si stanno spostando da Maven Central a un repository che richiede autenticazione.
I test come rete di sicurezza
Prima di cambiare qualsiasi versione, fissate il comportamento attuale con test di caratterizzazione: test che registrano ciò che il sistema fa oggi, non ciò che dovrebbe fare. I più utili stanno ai confini: risposte REST (inclusa la serializzazione JSON, che Jackson 3 può cambiare), messaggi pubblicati e righe scritte dalle transazioni critiche.
Eseguiteli su infrastruttura reale con Testcontainers, non su database in memoria che nascondono le differenze di dialetto e di tipo. Su Boot 2.7 le proprietà del container si collegano con @DynamicPropertySource; da Boot 3.1 lo fa @ServiceConnection:
@Testcontainers
@SpringBootTest
@AutoConfigureMockMvc
class OrderApiCharacterizationTest {
@Container
@ServiceConnection
static PostgreSQLContainer postgres = new PostgreSQLContainer("postgres:16");
// registrare le risposte di oggi, verificare che restino invariate a ogni passo
}
Boot 4.0 passa a Testcontainers 2.0, i cui moduli hanno nuovi nomi di artefatto (per esempio testcontainers-postgresql): anche il codice di test va migrato. Cambiate l'infrastruttura del test, non le asserzioni. Per le API usate da altri team, i test di contratto proteggono ciò che esponete.
Igiene delle dipendenze e CVE
L'upgrade è anche il momento per riprendere il controllo delle dipendenze:
- Lasciate al BOM di Spring Boot la gestione delle versioni; ogni override manuale deve avere una motivazione scritta.
- Prima di ogni passo verificate la compatibilità delle dipendenze non gestite da Boot, come Spring Cloud.
- Individuate presto le librerie abbandonate: sono la causa più frequente di un upgrade che si blocca.
- Generate un SBOM (CycloneDX) nella build e analizzatelo in CI. Da Spring Boot 3.3 Actuator può esporlo con un endpoint dedicato.
- Dopo il rilascio continuate ad applicare le patch release: è lì che arrivano le correzioni di sicurezza.
Rilascio: piccoli passi reversibili
Ogni passo va in produzione da solo, con un piano di rollback concordato in anticipo:
- Un cambiamento per rilascio: l'upgrade di Java, una minor di Boot e una modifica di comportamento di Hibernate non escono insieme.
- Modifiche al database in modalità expand/contract: prima si aggiungono nuove sequence o colonne, le vecchie si rimuovono solo quando la nuova versione è stabile, così la release precedente può ancora girare.
- Rilascio canary o blue/green, confrontando tassi di errore, latenza e numero di query tra istanze vecchie e nuove. Boot 4 attiva di default le probe di liveness e readiness, utili su Kubernetes.
- Feature flag per i comportamenti che cambiate intenzionalmente durante l'upgrade, per esempio una query riscritta.
Checklist
- Linea di destinazione scelta e date di supporto documentate
- Java aggiornato separatamente, sulla versione attuale di Boot
- Deprecazioni eliminate; properties migrator aggiunto e poi rimosso
- Dipendenze
javaxcensite e alternative Jakarta individuate - Sequence, tipi e fetching di Hibernate verificati su un database simile alla produzione
- Test di caratterizzazione e di integrazione verdi prima e dopo ogni passo
- Modifiche di OpenRewrite revisionate, termini di licenza verificati
- Rilascio con canary e rollback provato
Riferimenti ufficiali: guida di migrazione a Spring Boot 3.0, guida di migrazione a Spring Boot 4.0, guide di migrazione di Hibernate 6.0 e 7.0.
Se vi serve aiuto per pianificare o eseguire l'upgrade, trovate il nostro servizio di modernizzazione e lo Sprint di modernizzazione Spring, oppure contattateci.
Raccontateci il vostro sistema.
Descrivete la sfida in poche righe: una piattaforma da modernizzare, un incidente che si ripete, una vulnerabilità da chiudere, un'idea di AI. Rispondiamo personalmente, di solito entro due giorni lavorativi.