Contactez-nous

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é :

  1. Outils de développement (Devtools) : Paramètres globaux de Spring Boot Devtools sur votre machine locale (~/.spring-boot-devtools.properties).
  2. Annotations de Test : Les propriétés définies via @TestPropertySource dans vos tests JUnit ou TestNG.
  3. Attributs de Test : L'attribut properties de l'annotation @SpringBootTest.
  4. Arguments de ligne de commande : Passés via -- lors du lancement, par exemple --server.port=9000. Très haute priorité pour les surcharges ponctuelles.
  5. 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}}'.
  6. Propriétés Système Java : Définies via -D sur la ligne de commande Java, par exemple java -Dserver.port=9002 -jar app.jar.
  7. 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_PORT ou SERVER_DOT_PORT) à la clé de propriété correspondante (server.port).
  8. Fichiers application-{profile}.properties ou .yml spé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).
  9. Fichiers application-{profile}.properties ou .yml spécifiques aux profils, inclus à l'intérieur de votre JAR/WAR (dans src/main/resources).
  10. Fichiers application.properties ou .yml gé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).
  11. Fichiers application.properties ou .yml génériques, inclus à l'intérieur de votre JAR/WAR (dans src/main/resources). C'est la source de configuration par défaut la plus courante.
  12. Annotations @PropertySource : Fichiers de propriétés personnalisés chargés explicitement via cette annotation sur vos classes @Configuration.
  13. Propriétés par défaut : Définies via SpringApplication.setDefaultProperties dans 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é :

  1. Argument de ligne de commande : Définit le niveau à TRACE. C'est la priorité la plus élevée parmi les sources présentes ici.
  2. Variable d'environnement : Définit le niveau à INFO (priorité inférieure à la ligne de commande).
  3. Fichier de profil interne (application-debug.properties) : Définit le niveau à DEBUG (priorité inférieure à la variable d'environnement).
  4. 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/.yml inté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.