Chapitre 3: Configuration avec application.properties et application.yml
Introduction
La configuration est un aspect fondamental de toute application. Spring Boot offre un système de configuration puissant et flexible qui permet de personnaliser le comportement de l'application sans modifier le code.
Objectifs du Chapitre
À la fin de ce chapitre, vous serez capable de:
- Configurer une application avec application.properties et application.yml
- Utiliser les propriétés Spring Boot prédéfinies
- Créer des propriétés personnalisées
- Gérer différents environnements avec les profiles
- Externaliser la configuration
Fichiers de Configuration
Localisation
Spring Boot recherche les fichiers de configuration dans cet ordre:
Ordre de priorité (du plus haut au plus bas):
file:./config/application.propertiesfile:./config/application.ymlfile:./application.propertiesfile:./application.ymlclasspath:/config/application.propertiesclasspath:/config/application.ymlclasspath:/application.propertiesclasspath:/application.yml
En pratique: Placez vos fichiers dans src/main/resources/
Format application.properties
Syntaxe de Base
Format:
cle=valeur
Caractéristiques:
- Format clé-valeur simple
- Pas d'indentation
- Commentaires avec
# - Répétition des préfixes
Exemple Complet
# Configuration du serveur
server.port=8080
server.servlet.context-path=/api
# Nom de l'application
spring.application.name=greeting-app
# Configuration de la base de données
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=postgres
spring.datasource.password=secret
spring.datasource.driver-class-name=org.postgresql.Driver
# Configuration JPA
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
# Configuration des logs
logging.level.root=INFO
logging.level.com.example=DEBUG
logging.level.org.springframework.web=DEBUG
logging.file.name=logs/application.log
# Configuration Jackson (JSON)
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=America/Montreal
spring.jackson.serialization.indent-output=true
Avantages et Inconvénients
Avantages:
- Format simple et largement connu
- Compatible avec Java Properties
- Aucune dépendance externe
Inconvénients:
- Répétitif pour les structures hiérarchiques
- Moins lisible pour des configurations complexes
Format application.yml
Syntaxe de Base
Format: YAML (YAML Ain't Markup Language)
Caractéristiques:
- Format hiérarchique avec indentation
- Indentation = 2 ou 4 espaces (PAS de tabs)
- Structure en arbre
- Plus concis
Exemple Complet
# Configuration du serveur
server:
port: 8080
servlet:
context-path: /api
# Nom de l'application
spring:
application:
name: greeting-app
# Configuration de la base de données
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: postgres
password: secret
driver-class-name: org.postgresql.Driver
# Configuration JPA
jpa:
hibernate:
ddl-auto: update
show-sql: true
properties:
hibernate:
format_sql: true
dialect: org.hibernate.dialect.PostgreSQLDialect
# Configuration Jackson
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: America/Montreal
serialization:
indent-output: true
# Configuration des logs
logging:
level:
root: INFO
com.example: DEBUG
org.springframework.web: DEBUG
file:
name: logs/application.log
Avantages et Inconvénients
Avantages:
- Plus lisible pour les structures complexes
- Moins de répétition
- Support des listes et des maps
- Format moderne
Inconvénients:
- Sensible à l'indentation
- Erreurs de syntaxe plus fréquentes
- Nécessite une dépendance SnakeYAML (incluse par défaut)
Comparaison properties vs yml
Même Configuration dans les Deux Formats
application.properties:
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=postgres
spring.datasource.password=secret
application.yml:
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: postgres
password: secret
Tableau Comparatif
| Critère | properties | yml |
|---|---|---|
| Lisibilité | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Simplicité | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| Structure | Plate | Hiérarchique |
| Répétition | Beaucoup | Peu |
| Listes | Difficile | Facile |
| Compatibilité | Universel | Nécessite parser |
| Erreurs | Rares | Indentation |
Recommandation: Utilisez .yml pour des configurations complexes, .properties pour des configurations simples.
Propriétés Spring Boot Communes
1. Configuration du Serveur
server:
port: 8080 # Port du serveur
servlet:
context-path: /api # Chemin de base
compression:
enabled: true # Compression GZIP
error:
include-message: always # Inclure les messages d'erreur
2. Configuration de la Base de Données
PostgreSQL
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: postgres
password: secret
driver-class-name: org.postgresql.Driver
MySQL
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: secret
driver-class-name: com.mysql.cj.jdbc.Driver
H2 (Base de données en mémoire - Tests)
spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
h2:
console:
enabled: true # Console H2 accessible
path: /h2-console
3. Configuration JPA/Hibernate
spring:
jpa:
hibernate:
ddl-auto: update # none, validate, update, create, create-drop
show-sql: true # Afficher les requêtes SQL
properties:
hibernate:
format_sql: true # Formatter les requêtes
dialect: org.hibernate.dialect.PostgreSQLDialect
use_sql_comments: true # Commenter les requêtes
Valeurs de ddl-auto:
| Valeur | Description | Utilisation |
|---|---|---|
| none | Aucune action | Production |
| validate | Valider le schéma uniquement | Production |
| update | Mettre à jour le schéma | Développement |
| create | Créer le schéma au démarrage | Tests |
| create-drop | Créer puis supprimer | Tests |
4. Configuration des Logs
logging:
level:
root: INFO # Niveau global
com.example: DEBUG # Votre application
org.springframework.web: DEBUG # Spring Web
org.hibernate.SQL: DEBUG # Requêtes SQL
org.hibernate.type: TRACE # Paramètres SQL
pattern:
console: '%d{yyyy-MM-dd HH:mm:ss} - %msg%n'
file:
name: logs/application.log # Fichier de log
max-size: 10MB # Taille max par fichier
Niveaux de log:
TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF
5. Configuration Jackson (JSON)
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: America/Montreal
serialization:
indent-output: true # JSON indenté
write-dates-as-timestamps: false
deserialization:
fail-on-unknown-properties: false
6. Configuration DevTools
spring:
devtools:
restart:
enabled: true # Redémarrage automatique
livereload:
enabled: true # Rechargement du navigateur
Propriétés Personnalisées
Créer des Propriétés Personnalisées
application.yml:
app:
name: Greeting Application
version: 1.0.0
admin:
email: admin@example.com
phone: +1-514-123-4567
security:
jwt-secret: mySecretKey123
jwt-expiration: 86400000 # 24 heures en ms
Injection avec @Value
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class AppConfig {
@Value("${app.name}")
private String appName;
@Value("${app.version}")
private String appVersion;
@Value("${app.admin.email}")
private String adminEmail;
public void printConfig() {
System.out.println("Application: " + appName);
System.out.println("Version: " + appVersion);
System.out.println("Admin Email: " + adminEmail);
}
}
Classe de Configuration avec @ConfigurationProperties
Approche recommandée pour plusieurs propriétés:
application.yml:
app:
security:
jwt-secret: mySecretKey123
jwt-expiration: 86400000
allowed-origins:
- http://localhost:3000
- http://localhost:4200
Classe de configuration:
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
@ConfigurationProperties(prefix = "app.security")
public class SecurityProperties {
private String jwtSecret;
private Long jwtExpiration;
private List<String> allowedOrigins;
// Getters et Setters
public String getJwtSecret() {
return jwtSecret;
}
public void setJwtSecret(String jwtSecret) {
this.jwtSecret = jwtSecret;
}
public Long getJwtExpiration() {
return jwtExpiration;
}
public void setJwtExpiration(Long jwtExpiration) {
this.jwtExpiration = jwtExpiration;
}
public List<String> getAllowedOrigins() {
return allowedOrigins;
}
public void setAllowedOrigins(List<String> allowedOrigins) {
this.allowedOrigins = allowedOrigins;
}
}
Utilisation:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class AuthService {
@Autowired
private SecurityProperties securityProperties;
public void generateToken() {
String secret = securityProperties.getJwtSecret();
Long expiration = securityProperties.getJwtExpiration();
// Logique de génération de token
}
}
Gestion des Profiles
Concept des Profiles
Les profiles permettent d'avoir des configurations différentes selon l'environnement.
Créer des Profiles
Structure des fichiers:
src/main/resources/
├── application.yml # Configuration commune
├── application-dev.yml # Développement
├── application-test.yml # Tests
└── application-prod.yml # Production
Configuration par Profile
application.yml (commun):
spring:
application:
name: greeting-app
app:
name: Greeting Application
application-dev.yml:
server:
port: 8080
spring:
datasource:
url: jdbc:h2:mem:testdb
h2:
console:
enabled: true
logging:
level:
root: DEBUG
application-test.yml:
server:
port: 8081
spring:
datasource:
url: jdbc:h2:mem:testdb
logging:
level:
root: INFO
application-prod.yml:
server:
port: 80
spring:
datasource:
url: jdbc:postgresql://prod-db.example.com:5432/mydb
username: ${DB_USERNAME} # Variable d'environnement
password: ${DB_PASSWORD}
logging:
level:
root: WARN
file:
name: /var/log/app/application.log
Activer un Profile
Méthode 1: Dans application.yml
spring:
profiles:
active: dev
Méthode 2: Ligne de commande
java -jar app.jar --spring.profiles.active=prod
Méthode 3: Variable d'environnement
export SPRING_PROFILES_ACTIVE=prod
java -jar app.jar
Méthode 4: Dans l'IDE
VS Code (launch.json):
{
"configurations": [
{
"type": "java",
"name": "Spring Boot App",
"request": "launch",
"mainClass": "com.example.greeting.GreetingApplication",
"args": "--spring.profiles.active=dev"
}
]
}
Profiles Multiples
Vous pouvez activer plusieurs profiles:
java -jar app.jar --spring.profiles.active=dev,local
Ordre de priorité: Le dernier profile a la priorité
Variables d'Environnement
Utilisation
Spring Boot peut lire des variables d'environnement:
application.yml:
spring:
datasource:
url: ${DATABASE_URL:jdbc:postgresql://localhost:5432/mydb}
username: ${DATABASE_USER:postgres}
password: ${DATABASE_PASSWORD:secret}
Syntaxe: ${NOM_VARIABLE:valeur_par_defaut}
Définir des Variables
Windows (CMD):
set DATABASE_URL=jdbc:postgresql://prod-server:5432/mydb
set DATABASE_USER=admin
set DATABASE_PASSWORD=supersecret
java -jar app.jar
Windows (PowerShell):
$env:DATABASE_URL="jdbc:postgresql://prod-server:5432/mydb"
$env:DATABASE_USER="admin"
$env:DATABASE_PASSWORD="supersecret"
java -jar app.jar
Linux/macOS:
export DATABASE_URL=jdbc:postgresql://prod-server:5432/mydb
export DATABASE_USER=admin
export DATABASE_PASSWORD=supersecret
java -jar app.jar
Configuration Externalisée
Fichier de Configuration Externe
Spring Boot peut charger des fichiers de configuration externes:
Structure:
/opt/app/
├── app.jar
└── config/
└── application.yml
Lancement:
java -jar /opt/app/app.jar
Spring Boot trouvera automatiquement /opt/app/config/application.yml
Spécifier un Fichier
java -jar app.jar --spring.config.location=file:/path/to/config/
Propriétés Sensibles
Sécuriser les Mots de Passe
Mauvaise pratique:
spring:
datasource:
password: supersecret123 # ❌ Mot de passe en clair
Bonnes pratiques:
1. Variables d'environnement:
spring:
datasource:
password: ${DATABASE_PASSWORD} # ✅ Variable d'environnement
2. Spring Cloud Config Server:
- Centraliser la configuration
- Chiffrement des propriétés sensibles
3. HashiCorp Vault:
- Gestion professionnelle des secrets
4. Fichiers .env (développement uniquement):
DATABASE_PASSWORD=secret
Important: Ne JAMAIS commiter les mots de passe dans Git!
Exercices Pratiques
Exercice 1: Configuration de Base
Objectif: Configurer le port et le nom de l'application
Instructions:
- Créez un projet Spring Boot
- Dans
application.properties, configurez:- Port: 8081
- Nom: "My Greeting App"
- Démarrez l'application
- Vérifiez que le serveur démarre sur le port 8081
Exercice 2: Conversion properties → yml
Objectif: Convertir un fichier properties en yml
Fichier properties donné:
server.port=8080
spring.application.name=user-service
spring.datasource.url=jdbc:postgresql://localhost:5432/users
spring.datasource.username=admin
spring.jpa.show-sql=true
À faire: Convertissez en format YAML
Exercice 3: Propriétés Personnalisées
Objectif: Créer et utiliser des propriétés personnalisées
Instructions:
- Ajoutez dans
application.yml:app:
welcome-message: Bienvenue!
max-users: 100 - Créez un contrôleur qui affiche ces valeurs
- Testez
Exercice 4: Profiles
Objectif: Créer des profiles dev et prod
Instructions:
- Créez
application-dev.yml:- Port: 8080
- Logs: DEBUG
- Créez
application-prod.yml:- Port: 80
- Logs: WARN
- Testez l'activation de chaque profile
Questions de Révision
-
Quelle est la différence entre application.properties et application.yml?
-
Comment activer un profile Spring Boot?
-
Quel est l'ordre de priorité des fichiers de configuration?
-
Comment injecter une propriété personnalisée dans une classe?
-
Quelle annotation utiliser pour une classe de configuration avec plusieurs propriétés?
-
Comment utiliser une variable d'environnement dans application.yml?
-
Quelles sont les valeurs possibles pour
spring.jpa.hibernate.ddl-auto? -
Pourquoi ne jamais commiter les mots de passe dans application.properties?
Résumé du Chapitre
Points Clés
- Spring Boot supporte
.propertieset.yml .ymlest plus lisible pour les structures complexes- Les profiles permettent des configurations par environnement
@Valuepour une propriété,@ConfigurationPropertiespour plusieurs- Utiliser des variables d'environnement pour les données sensibles
- Ne jamais commiter les mots de passe
Bonnes Pratiques
- Utiliser des profiles pour chaque environnement
- Externaliser les configurations sensibles
- Documenter les propriétés personnalisées
- Fournir des valeurs par défaut
- Utiliser des noms de propriétés descriptifs
- Séparer configuration commune et spécifique
Prochaines Étapes
Dans le chapitre suivant, nous étudierons:
Chapitre 4: Annotations de Base
- @SpringBootApplication
- @RestController vs @Controller
- @GetMapping, @PostMapping, etc.
- @Autowired et injection de dépendances
- @Component, @Service, @Repository