
Priorité des sources de configuration (variables d'environnement, arguments de ligne de commande, etc.)
Démystifiez l'ordre de priorité dans lequel Spring Boot charge la configuration depuis les fichiers, variables d'environnement, arguments de ligne de commande, etc.
Un système hiérarchique : pourquoi l'ordre compte
Spring Boot offre une flexibilité remarquable en matière de configuration en permettant de définir des propriétés dans de nombreux endroits différents. Une application peut lire sa configuration depuis des fichiers .properties ou .yml intégrés dans le JAR, des fichiers externes au JAR, des variables d'environnement système, des propriétés système Java, des arguments de ligne de commande, et plus encore. Cette multitude de sources permet d'adapter finement le comportement de l'application à son environnement d'exécution sans avoir à modifier le code ou à reconstruire l'artefact.
Cependant, cette flexibilité soulève une question essentielle : que se passe-t-il si une même propriété (par exemple, server.port) est définie à plusieurs endroits différents avec des valeurs distinctes ? Laquelle sera utilisée par l'application ? Pour résoudre cela, Spring Boot établit une hiérarchie stricte des sources de configuration. Chaque source se voit attribuer une priorité, et les sources ayant une priorité plus élevée peuvent surcharger (override) les valeurs définies dans les sources de priorité inférieure.
Comprendre cet ordre de priorité est absolument crucial pour maîtriser la configuration de vos applications Spring Boot, prédire correctement quelle valeur sera utilisée dans une situation donnée, et déboguer efficacement les problèmes liés à la configuration.
L'ordre de priorité des sources courantes
Spring Boot examine un grand nombre d'emplacements pour les propriétés de configuration. Voici une liste simplifiée des sources les plus couramment utilisées, classées de la plus haute priorité (surcharge toutes les autres) à la plus basse priorité :
- Outils de développement (Devtools) : Paramètres globaux de Spring Boot Devtools sur votre machine locale (
~/.spring-boot-devtools.properties). - Annotations de Test : Les propriétés définies via
@TestPropertySourcedans vos tests JUnit ou TestNG. - Attributs de Test : L'attribut
propertiesde l'annotation@SpringBootTest. - Arguments de ligne de commande : Passés via
--lors du lancement, par exemple--server.port=9000. Très haute priorité pour les surcharges ponctuelles. - Propriétés de
SPRING_APPLICATION_JSON: Une propriété système ou une variable d'environnement contenant du JSON inline. Souvent utilisé dans les environnements cloud ou conteneurisés. Exemple:export SPRING_APPLICATION_JSON='{"server":{"port":9091}}'. - Propriétés Système Java : Définies via
-Dsur la ligne de commande Java, par exemplejava -Dserver.port=9002 -jar app.jar. - Variables d'Environnement Système : Variables définies au niveau du système d'exploitation. Spring Boot est intelligent et peut mapper les formats de variables d'environnement (par exemple,
SERVER_PORTouSERVER_DOT_PORT) à la clé de propriété correspondante (server.port). - Fichiers
application-{profile}.propertiesou.ymlspécifiques aux profils, situés à l'extérieur de votre JAR/WAR packagé (dans le même répertoire que le JAR, ou dans un sous-répertoire/config). - Fichiers
application-{profile}.propertiesou.ymlspécifiques aux profils, inclus à l'intérieur de votre JAR/WAR (danssrc/main/resources). - Fichiers
application.propertiesou.ymlgénériques, situés à l'extérieur de votre JAR/WAR packagé (dans le même répertoire que le JAR, ou dans un sous-répertoire/config). - Fichiers
application.propertiesou.ymlgénériques, inclus à l'intérieur de votre JAR/WAR (danssrc/main/resources). C'est la source de configuration par défaut la plus courante. - Annotations
@PropertySource: Fichiers de propriétés personnalisés chargés explicitement via cette annotation sur vos classes@Configuration. - Propriétés par défaut : Définies via
SpringApplication.setDefaultPropertiesdans votre code. (Priorité la plus basse).
Il existe encore d'autres sources (JNDI, ServletConfig, etc.), mais celles listées ci-dessus sont les plus pertinentes dans la plupart des cas d'utilisation de Spring Boot.
Exemple concret de surcharge
Imaginons le scénario suivant pour la propriété logging.level.org.springframework.web :
- Dans
src/main/resources/application.properties(inclus dans le JAR) :logging.level.org.springframework.web=WARN - Dans
src/main/resources/application-debug.properties(inclus dans le JAR) :logging.level.org.springframework.web=DEBUG - Une variable d'environnement est définie :
export LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_WEB=INFO - L'application est lancée avec le profil `debug` et un argument de ligne de commande :
java -jar myapp.jar --spring.profiles.active=debug --logging.level.org.springframework.web=TRACE
Quelle sera la valeur finale du niveau de log pour ce package ? Appliquons l'ordre de priorité :
- Argument de ligne de commande : Définit le niveau à
TRACE. C'est la priorité la plus élevée parmi les sources présentes ici. - Variable d'environnement : Définit le niveau à
INFO(priorité inférieure à la ligne de commande). - Fichier de profil interne (
application-debug.properties) : Définit le niveau àDEBUG(priorité inférieure à la variable d'environnement). - Fichier principal interne (
application.properties) : Définit le niveau àWARN(priorité la plus basse ici).
Par conséquent, la valeur qui l'emporte est celle de l'argument de ligne de commande : le niveau de log pour org.springframework.web sera TRACE.
Implications pratiques et flexibilité
Cette hiérarchie bien définie est extrêmement puissante pour plusieurs raisons :
- Configuration par défaut sûre : Vous pouvez mettre des valeurs par défaut raisonnables et non sensibles dans les fichiers
application.properties/.ymlintégrés à votre application. - Adaptation à l'environnement : Vous pouvez facilement surcharger ces valeurs par défaut pour chaque environnement (dev, test, prod) en utilisant des profils et/ou des fichiers externes, sans toucher à l'artefact packagé.
- Déploiement facilité : Dans les environnements conteneurisés (Docker, Kubernetes) ou cloud, il est très courant d'injecter la configuration via des variables d'environnement ou des volumes montés contenant des fichiers de configuration externes. La haute priorité de ces sources garantit qu'elles surchargeront les valeurs internes.
- Surcharges temporaires : Les arguments de ligne de commande et les propriétés système Java sont parfaits pour des surcharges temporaires lors de tests spécifiques, de débogage ou de lancements ponctuels avec des paramètres différents.
- Prédictibilité : Une fois que vous connaissez l'ordre de priorité, vous pouvez prédire avec certitude quelle valeur de configuration sera utilisée, ce qui simplifie le raisonnement et le diagnostic.
En résumé, le système de priorité des sources de configuration de Spring Boot est un mécanisme clé qui offre une grande flexibilité pour adapter votre application à n'importe quel environnement, tout en maintenant une structure de configuration de base claire et prévisible dans votre code source.