Spring a publié la version 2.4 de Spring Boot. Le but cet article est de faire un tour sur les principales évolutions de cette version mineure.
Spring Boot 2.4 requiert toujours un Java 8 minimum et propose un support de Java 15.
Deux versions contenant des bug fixes et des mises à jour de dépendances sont déjà disponibles : 2.4.1 et 2.4.2.
L’utilisation du nouveau système de numération des versions de Spring
Le premier changement concerne le numéro de version de Spring Boot qui applique le nouveau système de numérotation des versions de Spring. Ainsi la version devient 2.4.0 à la place de l’historique numéro de version qui aurait été 2.4.0.RELEASE.
La configuration
Plusieurs évolutions concernent la configuration.
Les raisons et le détail des changements sont décrits dans un article de blog sur Spring.io.
Le traitement des fichiers de configuration (.properties et .yaml)
Spring Boot 2.4 a modifié la manière dont les fichiers application.properties
et application.yml
sont traités. La mise à jour a été conçue pour simplifier et rationaliser la façon dont la configuration externe est chargée. Elle permet aussi de fournir de nouvelles fonctionnalités, telles que le support de l’importation de fichiers via la propriété spring.config.import
.
La mise à jour restreint intentionnellement certaines combinaisons de propriétés. Il y aura peut-être la nécessité de modifier certaines choses lors de la mise à jour à partir de Spring Boot 2.3 ou d’une version antérieure.
Si la configuration n’utilise qu’un simple fichier application.properties
ou application.yml
, la mise à niveau devrait être facile. En revanche, si la configuration est plus complexe (avec des propriétés spécifiques au profil ou des propriétés d’activation du profil), il faudra peut-être apporter quelques modifications pour utiliser les nouvelles fonctionnalités.
Un guide de mise à jour détaillé est disponible.
Pour avoir le comportement de Spring Boot 2.3, il faut mettre la propriété spring.config.use-legacy-processing
à true
dans le fichier de configuration application.properties
ou application.yml
.
L’import d’arborescence de type Volume Mounted
Une nouvelle propriété spring.config.import
peut être utilisée pour importer des arborescences de configuration qui sont couramment utilisés avec Kubernetes. Une arborescence de configuration est une autre façon de fournir des paires clé/valeur. Chaque paire est déclarée dans son propre fichier, le nom du fichier formant la clé de la propriété, et le contenu du fichier fournissant la valeur.
Le détail de l’utilisation et des exemples sont disponibles dans la documentation de référence.
Les chemins de configuration
Les chemins de configuration spécifiés via spring.config.location
et spring.config.import
(ajouté dans Spring Boot 2.4) n’échoueront plus silencieusement si le fichier ou le dossier n’existe pas. S’il faut importer un emplacement qui potentiellement ne sera pas trouvé, alors il est possible de préfixer le chemin avec optional:
Exemple :
[sourcecode language="bash"]
spring.config.location=optional:/etc/config/app.properties
[/sourcecode]
Il est possible de définir par configuration que tous les emplacements sont optionnels en utilisant :
- Soit la propriété
config.on-not-found=ignore
via la méthodeSpringApplication.setDefaultProperties(…)
- Soit avec une variable d’environnement système
La personnalisation du nom d’une propriété de configuration
Lors de l’utilisation de l’annotation @ConstructorBinding
, le nom de la propriété est dérivé du nom du paramètre. Cela peut poser un problème si l’on utilise un mot-clé réservé en Java. Dans ce cas, il est possible d’utiliser l’annotation @Name
pour préciser le nom de la propriété.
Exemple :
[sourcecode language="java"]
@ConfigurationProperties(prefix = "app")
@ConstructorBinding
public class MaConfigurationProperties {
private final String defaultValue;
public MaConfigurationProperties(@Name("default") String defaultValue) {
this.defaultValue = defaultValue;
}
}
[/sourcecode]
L’exemple ci-dessus permet d’utiliser la propriété app.default
.
L’importation de configurations supplémentaires
Tant que le paramètre spring.config.use-legacy-processing
n’est pas à true
, il est possible d’importer des fichiers properties et yaml supplémentaires directement à partir de fichier de configuration principal application.properties
ou application.yml
.
La propriété spring.config.import
permet de spécifier un ou plusieurs fichiers de configuration supplémentaires qui doivent être importés dans l’Environnement
Spring.
L’importation de fichiers de configuration sans extensions
Certaines plates-formes Cloud ne permettent que le montage de volumes de fichiers sans extension. Si l’on a une telle contrainte, il est maintenant possible d’importer ces fichiers en fournissant une information à Spring Boot sur le type de contenu.
Exemple de fichier qui sera considéré comme du YAML
[sourcecode language="bash"]
spring.config.import=/etc/maconfig[.yaml]
[/sourcecode]
Les propriétés de configuration de Logback
Les propriétés de configuration spécifiques à Logback ont été renommées pour refléter le fait qu’elles sont spécifiques à Logback. Les noms précédents ont été dépréciés.
Les propriétés concernées sont :
Avant Spring Boot 2.4 | A partir de Spring Boot 2.4 |
logging.pattern.rolling-file-name | logging.logback.rollingpolicy.file-name-pattern |
logging.file.clean-history-on-start | logging.logback.rollingpolicy.clean-history-on-start |
logging.file.max-size | logging.logback.rollingpolicy.max-file-size |
logging.file.total-size-cap | logging.logback.rollingpolicy.total-size-cap |
logging.file.max-history | logging.logback.rollingpolicy.max-history |
Les variables d’environnement système concernées sont :
Avant Spring Boot 2.4 | A partir de Spring Boot 2.4 |
ROLLING_FILE_NAME_PATTERN | LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN |
LOG_FILE_CLEAN_HISTORY_ON_START | LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START |
LOG_FILE_MAX_SIZE | LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE |
LOG_FILE_TOTAL_SIZE_CAP | LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP |
LOG_FILE_MAX_HISTORY | LOGBACK_ROLLINGPOLICY_MAX_HISTORY |
L’interface Origin
L’interface Origin
contient une nouvelle méthode getParent()
qui permet de fournir le chaînage complet de l’origine de l’élément.
Par exemple, lors de l’utilisation de spring.config.import
dans le fichier application.properties
pour importer un autre fichier, l’origine des propriétés chargées à partir de ce second fichier aura un parent qui renvoie à la déclaration d’importation originale.
Les endpoints /env
et /configprops
de l’Actuator utilisent ces informations.
http / web
Plusieurs évolutions concernent le web.
L’enregistrement de la servlet par défaut
Spring Boot 2.4 n’enregistre plus la DefaultServlet
fournie par le conteneur de servlets utilisé. Dans la plupart des applications, il n’est pas utilisé puisque la DispatcherServlet
de Spring MVC est la seule servlet nécessaire.
Vous pouvez configurer la propriété server.servlet.register-default-servlet
avec la valeur true
si vous avez besoin de la servlet par défaut.
Les classes annotées avec @WebListeners peuvent elles-mêmes enregistrer des servlets et des filtres
Les classes annotées avec @WebListener
sont désormais enregistrées de telle sorte qu’elles peuvent elles-mêmes enregistrer des servlets et des filtres.
Dans les versions précédentes de Spring Boot, il fallait les enregistrer manuellement en utilisant javax.servlet.Registration.Dynamic
.
A partir de Spring Boot 2.4, nous n’utilisons plus l’enregistrement dynamique et il est donc sûr d’appeler event.getServletContext().addServlet(…)
et event.getServletContext.addFilter(…)
dans la méthode ServletContextListener.contextInitialized()
.
Les nouvelles propriétés de configuration web
De nouvelles propriétés ont été ajoutées pour prendre en charge la configuration de Locale
et l’emplacement des ressources avec Spring MVC ou Spring WebFlux :
web.locale
web.locale-resolver
web.resources.*
Une nouvelle propriété a été ajoutée pour prendre en charge la configuration du endpoint de gestion des actuators via une servlet ou la pile web réactive :
server.base-path
Les propriétés spécifiques de Spring MVC et de servlet ci-dessous ont été dépréciées au profit de ces nouvelles propriétés qui supportent l’une ou l’autre des piles web :
mvc.locale
mvc.locale-resolver
resources.*
server.servlet.context-path
Actuator
Plusieurs évolutions concernent l’Actuator.
Le nouveau endpoint startup
Un nouveau endpoint nommé startup
permet d’obtenir des informations sur la séquence de démarrage de l’application. Ce endpoint peut aider à identifier les beans dont le démarrage est plus long que prévu.
Il s’appuie sur une fonctionnalité de Spring Framework 5.3.
Pour invoquer le endpoint, il faut faire un POST
sur l’url actuator/startup
.
[sourcecode language="bash"]
$ curl 'http://localhost:8080/actuator/startup' -i -X POST
[/sourcecode]
Les en-têtes HTTP relatives aux cookies dans les traces HTTP
Les en-têtes de requête Cookie
et les en-têtes de réponse Set-Cookie
ne sont plus inclus par défaut dans les traces HTTP.
Pour rétablir le comportement de Spring Boot 2.3, il faut définir la propriété management.trace.http.include
avec les valeurs cookies, errors, request-headers, response-headers
Filtrage dans le endpoint prometheus
Le endpoint prometheus
prend désormais en charge un paramètre de requête nommé includedNames
qui peut être utilisé pour filtrer les informations incluses dans la réponse.
Pour invoquer le endpoint, il faut un GET
sur l’url actuator/prometheus
avec un paramètre de requête includedNames
.
[sourcecode language="bash"]
$ curl 'http://localhost:8080/actuator/prometheus?includedNames=jvm_memory_used_bytes%2Cjvm_memory_committed_bytes' -i -X GET
[/sourcecode]
Buildpack / Docker
Plusieurs évolutions concernent la génération d’image Docker via Buildpack en utilisant Spring Boot.
La publication dans un registre Docker
Le goal Maven spring-boot:build-image
et la tâche bootBuildImage
du plugin Gradle peuvent maintenant publier l’image générée dans un registre Docker.
[sourcecode language="xml"]
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<name>docker.www.oxiane.com/library/${project.artifactId}</name>
<publish>true</publish>
</image>
<docker>
<publishRegistry>
<username>user</username>
<password>secret</password>
<url>https://registry.www.oxiane.com/</url>
<email>user@www.oxiane.com</email>
</publishRegistry>
</docker>
</configuration>
</plugin>
</plugins>
</build>
</project>
[/sourcecode]
L’authentification sur un registre privé Docker pour le build
Lors de la création d’une image Docker avec Spring Boot, il est maintenant possible d’obtenir les images requises par le build à partir d’un registre Docker privé avec authentification. L’authentification par nom d’utilisateur/mot de passe et par jeton est prise en charge.
Exemple avec Maven
[sourcecode language="xml"]
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<docker>
<builderRegistry>
<username>user</username>
<password>secret</password>
<url>https://registry.www.oxiane.com/</url>
<email>user@www.oxiane.com</email>
</builderRegistry>
</docker>
</configuration>
</plugin>
</plugins>
</build>
</project>
[/sourcecode]
Layered jar activé par défaut
Spring Boot 2.4 active les layered jars par défaut et inclut les layertools. Cela devrait améliorer l’efficacité de l’image générée utilisant le buildpack.
Out-of-the-box, plusieurs couches sont définies :
- dependencies : pour les dépendances
- spring-boot-loader : pour ce qui est dans org/springframework/boot/loader
- snapshot-dependencies : pour les dépendances snapshot
- application: pour l’application (classes et ressources)
Cela permet d’optimiser l’image générée en définissant un index du contenu de chaque couche.
L’image Paketo de Buildpack
Le constructeur d’images utilisé par le goal Maven spring-boot:build-image
et la tâche Gradle bootBuildImage
de Gradle a été mis à jour pout utiliser les dernières images Paketo.
Le registre des images Paketo a été modifié pour le Docker Hub à la place de Google Container Registry pour une meilleure accessibilité.
Les dépendances d’un projet multi-modules dans Maven
Le goal spring-boot:build-image
de Maven ajoute maintenant toutes les dépendances d’un projet multi-modules dans la couche « application ».
Deux nouveaux tags XML et
permettent de configurer les couches dans le fichier de configuration.
Les dépendances d’un projet multi-modules dans Gradle
La tâche bootBuildImage
de Gradle ajoute maintenant toutes les dépendances d’un projet multi-modules dans la couche « application ».
Il est possible d’utiliser includeProjectDependencies()
et excludeProjectDependencies()
dans le DSL pour configurer les couches.
Mises à jour des dépendances
Spring Boot 2.4 a mis à jour plusieurs versions des dépendances vers des projets Spring :
|
Spring Boot 2.4 a aussi a mis à jour plusieurs versions des dépendances vers des projets tiers :
|
|
|
Le support des dépendances tierces
Plusieurs évolutions concernent le support de certaines dépendances tierces.
La détection des bases de données embarquées
La manière dont une base de données embarquée est détectée a été affinée pour considérer qu’une base de données n’est embarquée que si elle est en mémoire.
Ce changement a deux conséquences si l’on utilise la persistance basée sur les fichiers ou le mode serveur avec H2, HSQL et Derby :
- L’utilisateur
sa
n’est plus configuré par défaut. Il faut maintenant le définir explicitement en définissant dans la configuration la propriété datasource.username=sa - Ces bases de données ne seront plus initialisées au démarrage car elles ne sont plus considérées comme embarquées. Pour le faire il faut utiliser la propriété datasource.initialization-mode
Une propriété de configuration pour le mot de passe admin de la console web H2
Une nouvelle propriété de configuration, spring.h2.console.settings.web-admin-password
permet de configurer le mot de passe administrateur de la console web H2.
Neo4j
Spring Boot 2.4 apporte une mise à jour significative du support de Neo4j. Un certain nombre de propriétés spring.data.neo4j.*
ont été supprimées et le support de Neo4j OGM a également été supprimé.
La configuration du pilote Neo4j se fait via l’espace de noms spring.neo4j.*
bien que l’URI et l’authentification de base à partir de l’espace de noms data soient toujours supportés de manière dépréciée.
Cette version apporte le support des reactive repositories et repose sur une auto-configuration séparée pour le driver Neo4j. Il est donc maintenant possible d’utiliser Neo4j avec ou sans Spring Data.
Pour utiliser @Transactional
avec une utilisation réactive, il faut configurer explicitement le bean Neo4jReactiveTransactionManager
.
[sourcecode language="java"]
@Bean(ReactiveNeo4jRepositoryConfigurationExtension.DEFAULT_TRANSACTION_MANAGER_BEAN_NAME)
public ReactiveTransactionManager reactiveTransactionManager(Driver driver, ReactiveDatabaseSelectionProvider databaseNameProvider){
returnnewReactiveNeo4jTransactionManager(driver, databaseNameProvider);
}
[/sourcecode]
Hazelcast 4
Spring Boot 2.4 utilise Hazelcast 4 tout en conservant la compatibilité avec Hazelcast 3.2.x. Si vous n’êtes pas prêt à passer à Hazelcast 4, il faut utiliser la propriété hazelcast.version
dans la configuration du build.
Elasticsearch RestClient
Le bean Elasticsearch RestClient
n’est plus auto-configuré par Spring Boot. Le bean RestHighLevelClient
est toujours auto-configuré.
R2DBC
L’infrastructure de base de R2DBC est passée dans Spring Framework dans un nouveau module spring-r2dbc
. L’utilisation de cette infrastructure nécessite de migrer les accès dépréciés vers le nouveau support de base.
Un R2dbcEntityTemplate
est disponible pour simplifier l’utilisation de Reactive R2DBC par les entités.
Redis Cache Metrics
Lors de l’utilisation du cache Redis, il est possible d’exposer les statistiques du cache via Micrometer. Les mesures enregistrées comprennent le nombre de puts, de gets et de deletes, ainsi que le nombre de hits/misses. Le nombre de demandes en attente et la durée d’attente du verrouillage sont également enregistrés.
Pour activer cette fonctionnalité, il faut définir la propriété spring.cache.redis.enable-statistics
avec la valeur true
.
Les tests automatisés
Plusieurs évolutions concernent les tests automatisés.
Le Vintage Engine de JUnit 5 est retiré de spring-boot-starter-test
A partir de spring Boot 2.4, le starter spring-boot-starter-test
n’inclut plus le moteur d’exécution des tests JUnit 4 (Vintage Engine) dans JUnit 5.
Si la migration des tests vers JUnit 5 n’est pas envisagée, il faut rajouter manuellement la dépendance.
Exemple avec Maven :
[sourcecode language="xml"]
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
[/sourcecode]
Exemple avec Gradle :
[sourcecode language="json"]
testImplementation("org.junit.vintage:junit-vintage-engine") {
excludegroup:"org.hamcrest",module:"hamcrest-core"
}
[/sourcecode]
L’exportation des métriques dans les tests d’intégration
L’annotation @SpringBootTest
ne configure plus les systèmes de surveillance disponibles et ne fournit que MeterRegistry
en mémoire. Si l’on exportait des métriques dans le cadre d’un test d’intégration, il est possible d’ajouter l’annotation @AutoConfigureMetrics
aux tests pour rétablir le comportement précédent.
Conclusion
Spring Boot poursuit son évolution au travers de cette version mineure. La migration vers cette nouvelle version pourra dans certains cas nécessiter quelques adaptations.