Blog - Road to GA (série d'articles sur les nouveautés)
spring-retry est en fin de vie et certaines fonctionnalités sont incluse dans Spring core 7.
Sur la méthode
@Retryable(delayString = "300ms", multiplier = 1.5, jitterString = "200ms")
PlayerStats getPlayerStats(String playerId) {
...
}Activation dans la config
@EnableResilientMethods
public class Application {
...
}
Spring 7+ supporte le versioning des APIs REST :
Niveau @Controller
@RequestMapping(path="/api", produces=MediaType.APPLICATION_JSON_VALUE, version="1.0+")
public class ApiController {
@GetMapping(path="/queue/stats", version="1.1")
public QueueStats queueStats() {
...
}Niveau config
@Configuration(proxyBeanMethods = false)
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void configureApiVersioning(ApiVersionConfigurer configurer) {
// alternative 1 : par défaut
WebMvcConfigurer.super.configureApiVersioning(configurer);
// alternative 2 : manuel
configurer.useRequestHeader("API-Version")
.addSupportedVersions("1.0", "1.1")
.setDefaultVersion(1.1");
}
} Source :
Spring 7 Road to GA - API Versioning in Spring
Paris JUG - Spring Boot: Chapitre 4
Slides : https://2024.springio.net/slides/spring-framework-62-core-container-revisited-springio24.pdf
- Fast path for bean name matching (before was occuring after by type matching as a last resort).
NB : needs
-parameterscompile option to preserve parameters name.
Reminder on bean configuration ways (not new) :
// by bean name
@Bean
public DataSource commonDataSource() {
...
}
@Bean
public MyRepository repository(DataSource commonDataSource) {
...
}
// by qualifier
@Bean @MyQualifier
public DataSource commonDataSource() {
...
}
@Bean
public MyRepository repository(@MyQualifier DataSource ds) {
...
}
// by bean name + qualifier
@Bean
public DataSource commonDataSource() {
...
}
@Bean
public MyRepository repository(
@Qualifier("commonDataSource") DataSource dataSource) {
...
}- @Fallback (inverse of @Primary) : mostly useful in configurations where tierce modules beans are not under our responsabilities (ie. theirs as regular beans + ours as @Fallback beans).
@Bean
public DataSource commonDataSource() { // only non-fallback
...
}
@Bean @Fallback
public DataSource otherDataSource() {
...
}- Singleton initialization lock mecanism rewritten (from synchronized to reentrant lock based).
Lifecycle management
@Bean
public ThreadPoolTaskExecutor taskExecutor() {
…
executor.setPhase(...);
…
}
@Bean
public ThreadPoolTaskScheduler taskScheduler() {
…
scheduler.setPhase(...);
…
}https://spring.io
https://spring.io/blog
https://start.spring.io
Chaîne YT SpringDeveloper
Chaîne YT Spring I/O
2.0 : Prez par Phil Webb et Madhura Bhave
2.3 : Prez par Phil Webb
2.4 : Prez par Phil Webb
2.6 : Prez par Dan Vega
3.0-SNAPSHOT (26 oct 2022) : Mini préz avant 1ère par Josh Long
3.2 : Tips by Josh Long
Retrospective (2025-01-30) : Spring Boot co-creator Phil Webb and its biggest fan Josh Long look at its first ten whole years!
Demo app Spring Boot 4 par Brian Clozel et
management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=*
URLs de quelques endpoints :
/actuator/actuator/configprops/actuator/env/<prop>
Depuis 2.3, nouvelle propriété server.shutdown=immediate (par défaut)
ou plus user-friendly server.shutdown=graceful en combinaison avec spring.lifecycle.timeout-per-shutdown-phase=20s
Prendre exemple sur ServerProperties au sein de Spring Boot.
import org.springframework.boot.convert.DurationUnit;
import org.springframework.boot.context.properties.bind.Name;
@ConfigurationProperties("my.service")
@DefaultValue("USER") List<String> roles
@DefaultValue Security security // utile pour avoir une instance au lieu de null
@ConstructorBinding // utile si plusieurs constructeurs
@DurationUnit(ChronoUnit.SECONDS) Duration forTime // unité par défaut si non spécifié dans la config
@Name("for") Duration forUnit // utile pour nommer une propriété sans contrainte de mot clé javaSpringApplication.run(DemoApplication.class, args) est un raccourci de new SpringApplication(DemoApplication.class).run(args).
La version "non raccourcie" permet de configurer en détail l'objet SpringApplication, par exemple attacher un ApplicationStartup (2.4).
SpringApplication springApplication = new SpringApplication(DemoApplication.class);
springApplication.setApplicationStartup(new FlightRecorderApplicationStartup());
springApplication.run(args);java -XX:StartFlightRecording:filename=recording.jfr,duration=10s -jar app.jarOu encore d'attacher des properties programatiquement :
SpringApplication springApplication = new SpringApplication(DemoApplication.class);
Properties properties = new Properties();
properties.put("spring.batch.job.enabled", false);
application.setDefaultProperties(properties);Depuis la 2.3, https://www.youtube.com/watch?v=WL7U-yGfUXA&t=1566s.
Endpoint actuator :
/actuator/health/actuator/health/liveliness/actuator/health/readiness
Il est possible de changer l'état
@Autowired
private ApplicationEventPublisher publisher;
AvailabilityChangeEvent.publish(publisher, this, ReadinessState.REFUSING_TRAFFIC);
AvailabilityChangeEvent.publish(publisher, this, ReadinessState.ACCEPTING_TRAFFIC);Depuis la 2.4, spring.config.import pour splitter la configuration qui est plus souple que les profils à cet effet.
L'extension est aussi optionnelle grâce à la syntaxe [.extension]. Dans l'exemple, les deux fichiers ext et ext.properties sont acceptés.
Aussi, les propriétés peuvent provenir d'une arborescence à la manière d'Ansible ou de Kubernetes (niveau intermédiaire = dossier, feuille = fichier). L'arborescence doit exister par défaut, mais le mot clef optional permet de passer outre l'erreur.
A la manière de configtree, il est possible d'implémenter son propre type d'import. S'inspirer des classes ConfigTreeConfigDataLocationResolver implements ConfigDataLocationResolver<ConfigTreeConfigDataResource> et ConfigTreeConfigDataLoader implements ConfigDataLoader<ConfigTreeConfigDataResource>. Vu dans https://www.youtube.com/watch?v=lgyO9C9zdrg&t=2451s.
spring.config.import=classpath:example1.properties,classpath:example2.properties
spring.config.import=file:${user.home}/demo/ext[.properties]
spring.config.import=optional:configtree:${user.home}/demos/tree/Actuator insights :
- Pour les imports complexes (eg. chainés),
/actuator/configpropsaffiche les propriétés et le fichier properties d'origine où elles sont définies. /actuator/env/<prop>donne le détail pour une propriété.
spring:
application:
name: "test"
---
spring:
profiles: "prod"
application:
name: "test-prod"Depuis la 2.4, construction multi docs supportée dans les fichiers properties.
La chaîne de caractère #--- est l'équivalent de --- en yaml.
Si plusieurs profils correspondent, la règle et que le dernier l'emporte, cad wait.for=5s dans l'exemple ci dessous.
Au passage, on remarque que l'on peut mettre une SpEL dans la propriété spring.profiles.
wait.for=1s
spring.profiles.active=test
#---
spring.profiles=prod | test
wait.for=10s
#---
spring.profiles=test
wait.for=5sDepuis la 2.4, la propriété spring.profiles est dépréciée au profit de spring.config.activate.on-profile, la raison étant que l'ancienne clé était un préfixe d'autres propriétés comme spring.profiles.active, ce qui est plus difficile à écrire en yaml par exemple.
Plusieurs variantes :
spring.config.activate.on-profile=prod | testspring.config.activate.on-cloud-platform=kubernetes(en combinaison avecspring.main.cloud-platform)
Coffe + Software with Spring Batch lead Mahmoud Ben Hassine - Sept 19th 2025
- retry lib moving to Spring core : legacy retry from Spring Batch still present for back compatibility and will be maintained this generation before removal
- by default state management will be opt in
- api is nullability compliant with jspecify
- redis repository coming in 6.1
- new concurrency model to minimize locking => performance gain
- metrics support with JFR

