Propriétés avec Spring et Spring Boot

Propriétés avec ressort et botte de printemps

1. Vue d'ensemble

Ce tutoriel montrera comment configurer et utiliserProperties in Spring - via la configuration Java et@PropertySource ou via XML et<property-placeholder>,as well how properties work in Spring Boot.

Lectures complémentaires:

Guide du langage Spring Expression

Cet article explore le langage d'expression Spring (SpEL), un langage d'expression puissant qui prend en charge la requête et la manipulation de graphiques d'objet lors de l'exécution.

Read more

Configurer une application Web Spring Boot

Certaines des configurations les plus utiles pour une application Spring Boot.

Read more

Guide de @ConfigurationProperties in Spring Boot

Guide rapide et pratique sur les annotations @ConfigurationProperties dans Spring Boot.

Read more

2. Enregistrer un fichier de propriétés via des annotations Java

Spring 3.1 introduit égalementthe new @PropertySource annotation, comme un mécanisme pratique pour ajouter des sources de propriété à l'environnement. Cette annotation doit être utilisée en conjonction avec la configuration basée sur Java et l'annotation@Configuration:

@Configuration
@PropertySource("classpath:foo.properties")
public class PropertiesWithJavaConfig {
    //...
}

Un autre moyen très utile d'enregistrer un nouveau fichier de propriétés consiste à utiliser un espace réservé pour vous permettre dedynamically select the right file at runtime; par exemple:

@PropertySource({
  "classpath:persistence-${envTarget:mysql}.properties"
})
...

2.1. Définir plusieurs emplacements de propriété

L'annotation@PropertySource est répétableaccording to Java 8 conventions. Par conséquent, si nous utilisons Java 8 ou une version ultérieure, nous pouvons utiliser cette annotation pour définir plusieurs emplacements de propriété:

@PropertySource("classpath:foo.properties")
@PropertySource("classpath:bar.properties")
public class PropertiesWithJavaConfig {
    //...
}

Bien sûr, nous pouvons également utiliser l'annotation@PropertySources et spécifier un tableau de@PropertySource. Cela fonctionne dans toutes les versions Java prises en charge, pas seulement dans Java 8 ou supérieur:

@PropertySources({
    @PropertySource("classpath:foo.properties"),
    @PropertySource("classpath:bar.properties")
})
public class PropertiesWithJavaConfig {
    //...
}

Dans les deux cas, il convient de noter quein the event of a property name collision, the last source read takes precedence.

3. Enregistrer un fichier de propriétés au format XML

En XML, les nouveaux fichiers de propriétés peuvent être rendus accessibles à Spring viathe <context:property-placeholder … > namespace element:

Le fichierfoo.properties doit être placé sous/src/main/resources afin qu'il soit disponible sur le chemin des classes lors de l'exécution.

Dans le cas oùmultiple <property-placeholder> elements sont présents dans le contexte Spring, il existe quelques bonnes pratiques recommandées:

  • l'attributorder doit être spécifié pour fixer l'ordre dans lequel ceux-ci sont traités par Spring

  • tous les espaces réservés de propriété moins le dernier (lesorder les plus élevés) doivent avoirignore-unresolvable=”true” pour permettre au mécanisme de résolution de passer à d'autres dans le contexte sans lever d'exception

3.1. Enregistrer plusieurs fichiers de propriétés dans XML

Dans la section précédente, nous avons vu comment définir plusieurs fichiers de propriétés à l'aide d'annotations dans Java 8 ou ultérieur. De même, nous pouvonsdefine multiple properties files using XML configuration:

Et, comme auparavant,in the event of a property name collision, the last source read takes precedence.

4. Utilisation / Injection de propriétés

Injecting a property with the @Value annotation est simple:

@Value( "${jdbc.url}" )
private String jdbcUrl;

A default value of the property peut également être spécifié:

@Value( "${jdbc.url:aDefaultUrl}" )
private String jdbcUrl;

Utilisation des propriétés dans la configuration XML de Spring:


  

Les anciensPropertyPlaceholderConfigurer et les nouveauxPropertySourcesPlaceholderConfigurer ajoutés dans Spring 3.1resolve $\{…} placeholders dans les valeurs de propriété de définition de bean et les annotations@Value.

Enfin - nous pouvons obtain the value of a property using the Environment API:

@Autowired
private Environment env;
...
dataSource.setUrl(env.getProperty("jdbc.url"));

Une mise en garde très importante ici est queusing <property-placeholder> will not expose the properties to the Spring Environment - cela signifie que récupérer la valeur comme celle-ci ne fonctionnera pas - il renverranull:

env.getProperty("key.something")

5. Propriétés avec Spring Boot

Avant de passer à des options de configuration plus avancées pour les propriétés, passons un peu de temps à examinerthe new properties support in Spring Boot.

De manière générale, ce nouveau support impliqueless configuration par rapport au Spring standard, ce qui est bien sûr l'un des principaux objectifs de Boot.

5.1. application.properties - le fichier de propriétés par défaut

Boot applique sa convention typique sur la configuration aux fichiers de propriétés. Cela signifie que nous pouvons simplement mettre un fichier «application.properties» dans notre répertoire «src/main/resources», et il sera détecté automatiquement. Nous pouvons ensuite injecter toutes les propriétés chargées normalement.

Ainsi, en utilisant ce fichier par défaut, nous n’avons pas à enregistrer explicitement unPropertySource, ni même à fournir un chemin vers un fichier de propriétés.

Nous pouvons également configurer un fichier différent au moment de l'exécution, si nécessaire, en utilisant une propriété d'environnement:

java -jar app.jar --spring.config.location=classpath:/another-location.properties

5.2. Fichier de propriétés spécifiques à l'environnement

Si nous devons cibler différents environnements, il existe un mécanisme intégré pour cela dans Boot.

Nous pouvons simplement définir un fichier“application-environment.properties” dans le répertoire“src/main/resources” - puis définir un profil Spring avec le même nom d'environnement.

Par exemple, si nous définissons un environnement «intermédiaire», cela signifie que nous devrons définir un profilstaging puisapplication-staging.properties.

Ce fichier env sera chargé etwill take precedence over the default property file. Notez que le fichier par défaut sera toujours chargé, c'est simplement qu'en cas de collision de propriétés, le fichier de propriétés spécifique à l'environnement est prioritaire.

5.3. Fichier de propriétés spécifiques au test

Nous pourrions également être obligés d'utiliser différentes valeurs de propriété lorsque notre application est testée.

Spring Boot gère cela pour nous en regardant dans notre répertoire «src/test/resources» lors d'un test. Encore une fois, les propriétés par défaut seront toujours injectables comme d'habitude, mais elles seront remplacées en cas de collision.

5.4. L'annotation@TestPropertySource

Si nous avons besoin d'un contrôle plus granulaire sur les propriétés des tests, nous pouvons utiliser l'annotation@TestPropertySource.

Cela nous permet de définir les propriétés de test pour un contexte de test spécifique, en prenant le pas sur les sources de propriétés par défaut:

@ContextConfiguration
@TestPropertySource("/my-test.properties")
public class IntegrationTests {
    // tests
}

Si nous ne voulons pas utiliser de fichier, nous pouvons spécifier directement des noms et des valeurs:

@ContextConfiguration
@TestPropertySource("foo=bar", "bar=foo")
public class IntegrationTests {
    // tests
}

Nous pouvons également obtenir un effet similaire en utilisant l'argumentproperties de l'annotation@SpringBootTest:

@SpringBootTest(properties = {"foo=bar", "bar=foo"})
public class IntegrationTests {
    // tests
}

5.5. Propriétés hiérarchiques

Si nous avons des propriétés qui sont regroupées, nous pouvons utiliser l'annotation@ConfigurationProperties qui mappera ces hiérarchies de propriétés dans des graphiques d'objets Java.

Prenons quelques propriétés utilisées pour configurer une connexion à une base de données:

database.url=jdbc:postgresql:/localhost:5432/instance
database.username=foo
database.password=bar

Et puis utilisons l'annotation pour les mapper à un objet de base de données:

@ConfigurationProperties(prefix = "database")
public class Database {
    String url;
    String username;
    String password;

    // standard getters and setters
}

Spring Boot applique à nouveau sa convention sur l'approche de configuration, mappant automatiquement entre les noms de propriété et leurs champs correspondants. Tout ce que nous devons fournir est le préfixe de propriété.

Si vous souhaitez approfondir les propriétés de configuration, jetez un œil àthe in-depth article.

5.6. Alternative - Fichiers YAML

Les fichiers YAML sont également pris en charge.

Toutes les règles de dénomination s'appliquent aux fichiers de propriétés par défaut, spécifiques à un test, spécifiques à l'environnement. La seule différence est l'extension de fichier et une dépendance de la bibliothèqueSnakeYAML sur votre chemin de classe.

YAML est particulièrement utile pour le stockage de propriété hiérarchique; le fichier de propriétés suivant:

database.url=jdbc:postgresql:/localhost:5432/instance
database.username=foo
database.password=bar
secret: foo

Est-ce le fichier YAML suivant:

database:
  url: jdbc:postgresql:/localhost:5432/instance
  username: foo
  password: bar
secret: foo

Il convient également de mentionner que les fichiers YAML ne prennent pas en charge l'annotation@PropertySource, donc si l'utilisation de l'annotation était requise, cela nous obligerait à utiliser un fichier de propriétés.

5.7. Propriétés des arguments de ligne de commande

Contrairement à l'utilisation de fichiers, les propriétés peuvent être passées directement sur la ligne de commande:

java -jar app.jar --property="value"

Vous pouvez également le faire via les propriétés système, qui sont fournies avant la commande-jar plutôt qu'après:

java -Dproperty.name="value" -jar app.jar

5.8. Propriétés des variables d'environnement

Spring Boot détectera également les variables d’environnement en les traitant comme des propriétés:

export name=value
java -jar app.jar

5.9 Randomization of Property Values

Si nous ne voulons pas de valeurs de propriété déterministes,RandomValuePropertySource peut être utilisé pour randomiser les valeurs des propriétés:

random.number=${random.int}
random.long=${random.long}
random.uuid=${random.uuid}

5.10. Types supplémentaires de sources de propriété

Spring Boot prend en charge une multitude de sources de propriétés, mettant en œuvre un ordre bien pensé pour permettre un dépassement raisonnable. Il vaut la peine de consulter lesofficial documentation, qui vont plus loin que la portée de cet article.

6. Configuration à l'aide de Raw Beans dans Spring 3.0 - lesPropertyPlaceholderConfigurer

Outre les méthodes pratiques pour obtenir des propriétés dans Spring - les annotations et l'espace de noms XML - le bean de configuration de propriété peut également être défini et enregistrémanually. Travailler avec lesPropertyPlaceholderConfigurer nous donne un contrôle total sur la configuration, avec l'inconvénient d'être plus verbeux et la plupart du temps, inutile.

6.1. Configuration Java

@Bean
public static PropertyPlaceholderConfigurer properties() {
    PropertyPlaceholderConfigurer ppc
      = new PropertyPlaceholderConfigurer();
    Resource[] resources = new ClassPathResource[]
      { new ClassPathResource( "foo.properties" ) };
    ppc.setLocations( resources );
    ppc.setIgnoreUnresolvablePlaceholders( true );
    return ppc;
}

6.2. Configuration XML


    
        
            classpath:foo.properties
        
    
    

7. Configuration utilisant Raw Beans dans Spring 3.1 - lesPropertySourcesPlaceholderConfigurer

De même, dans Spring 3.1, les nouveauxPropertySourcesPlaceholderConfigurer peuvent également être configurés manuellement:

7.1. Configuration Java

@Bean
public static PropertySourcesPlaceholderConfigurer properties(){
    PropertySourcesPlaceholderConfigurer pspc
      = new PropertySourcesPlaceholderConfigurer();
    Resource[] resources = new ClassPathResource[ ]
      { new ClassPathResource( "foo.properties" ) };
    pspc.setLocations( resources );
    pspc.setIgnoreUnresolvablePlaceholders( true );
    return pspc;
}

7.2. Configuration XML


    
        
            classpath:foo.properties
        
    
    

8. Propriétés dans les contextes parent-enfant

Cette question revient sans cesse - que se passe-t-il lorsque vosweb application has a parent and a child context? Le contexte parent peut avoir des fonctionnalités de base communes et des beans, puis un (ou plusieurs) contextes enfants, contenant éventuellement des beans spécifiques à une servlet.

Dans ce cas, quelle est la meilleure façon de définir les fichiers de propriétés et de les inclure dans ces contextes? De plus, comment récupérer au mieux ces propriétés à partir de Spring? Voici la ventilation simple.

8.1. Si le fichier de propriétés est défini en XML avec roperty-placeholder>

Si le fichier estdefined in the Parent context:

  • @Value fonctionne dansChild context: NON

  • @Value fonctionne dansParent context: OUI

Si le fichier estdefined in the Child context:

  • @Value fonctionne dansChild context: OUI

  • @Value fonctionne dansParent context: NON

Enfin, comme nous l'avons vu précédemment,<property-placeholder> n'expose pas les propriétés à l'environnement, donc:

  • environment.getProperty fonctionne danseither context: NON

8.2. Si le fichier de propriétés est défini en Java avec@PropertySource

Si le fichier estdefined in the Parent context:

  • @Value fonctionne dansChild context: OUI

  • @Value fonctionne dansParent context: OUI

  • environment.getProperty enChild context: OUI

  • environment.getProperty enParent context: OUI

Si le fichier estdefined in the Child context:

  • @Value fonctionne dansChild context: OUI

  • @Value fonctionne dansParent context: NON

  • environment.getProperty enChild context: OUI

  • environment.getProperty enParent context: NON

9. Conclusion

Cet article montre plusieursexamples of working with properties and properties files in Spring.

Comme toujours, l'intégralité du code supportant l'article est disponibleover on Github. Ceci est un projet basé sur Maven, il devrait donc être facile à importer et à exécuter tel quel.