Vue d’ensemble
Les expressions de propriété vous permettent de référencer d’autres propriétés de configuration au sein d’une valeur en utilisant la syntaxe ${key}. Celle-ci est évaluée avant la conversion de type et permet la composition et les valeurs par défaut.
Syntaxe de base
Expressions complexes
Combinez plusieurs références dans une seule valeur :
app.db.host=localhost
app.db.port=5432
app.db.name=mydb
app.db.url=jdbc:postgresql://${app.db.host}:${app.db.port}/${app.db.name}
String dbUrl = config.getValue("app.db.url", String.class);
// Résultat : "jdbc:postgresql://localhost:5432/mydb"
Expressions avec profils
Les expressions sont résolues après la correspondance des profils :
# Configuration de base
app.db.host=prod-db.example.com
%dev.app.db.host=localhost
# L'expression utilise la valeur résolue
app.db.url=jdbc:postgresql://${app.db.host}:5432/mydb
java -Dmp.config.profile=dev MyApplication
String dbUrl = config.getValue("app.db.url", String.class);
// Avec le profil dev actif : l'hôte résolu est "localhost"
// Résultat : "jdbc:postgresql://localhost:5432/mydb"
Détection de cycle
Si une expression de propriété se référence elle-même (directement ou indirectement), une IllegalArgumentException est levée :
# Cycle direct
app.value=${app.value}
# Cycle indirect
app.a=${app.b}
app.b=${app.a}
try {
config.getValue("app.value", String.class);
} catch (IllegalArgumentException e) {
System.err.println("Cycle détecté : " + e.getMessage());
}
Ravel détecte les cycles en utilisant un ScopedValue<Set<String>> pour suivre les clés en cours de résolution.
Notes de performance
-
Évaluation paresseuse — les expressions sont résolues uniquement quand la valeur est demandée
-
Pas de résolution répétée — la même expression dans une seule lookup n’est pas réévaluée
-
Thread-safe —
ScopedValueest compatible avec les virtual threads et supporte la concurrence structurée
Exemples
Composition multi-niveaux
company=Acme
department=Engineering
team.email=${company}-${department}@example.com
Résultat : team.email = Acme-Engineering@example.com
Drapeaux de fonctionnalité avec défauts
app.features.cache=true
app.cache.ttl=${app.cache.ttl:3600}
app.cache.maxsize=${app.cache.maxsize:1000}
URLs spécifiques à l’environnement
# Base
app.api.scheme=https
app.api.host=api.example.com
app.api.port=443
app.api.url=${app.api.scheme}://${app.api.host}:${app.api.port}/v1
# Surcharge dev
%dev.app.api.scheme=http
%dev.app.api.host=localhost
%dev.app.api.port=8080
Résultat (profil dev) :
- ${app.api.scheme} → http
- ${app.api.host} → localhost
- ${app.api.port} → 8080
- app.api.url → http://localhost:8080/v1
Suivant
-
Profils de configuration — configuration spécifique à l’environnement
-
Intégration CDI — injecter les valeurs résolues