Eigenschaften mit Spring und Spring Boot

Eigenschaften mit Feder und Spring Boot

1. Überblick

Dieses Tutorial zeigt, wie SieProperties in Spring einrichten und verwenden - über die Java-Konfiguration und@PropertySource oder über XML und<property-placeholder>,as well how properties work in Spring Boot.

Weitere Lektüre:

Sprachführer für Spring Expression

Dieser Artikel befasst sich mit Spring Expression Language (SpEL), einer leistungsstarken Ausdruckssprache, die das Abfragen und Bearbeiten von Objektdiagrammen zur Laufzeit unterstützt.

Read more

Konfigurieren Sie eine Spring Boot-Webanwendung

Einige der nützlicheren Konfigurationen für eine Spring Boot-Anwendung.

Read more

Anleitung zu @ConfigurationProperties in Spring Boot

Eine schnelle und praktische Anleitung für die @ ConfigurationProperties-Annotation in Spring Boot.

Read more

2. Registrieren Sie eine Eigenschaftendatei über Java Annotations

In Spring 3.1 wird außerdemthe new @PropertySource annotation als praktischer Mechanismus zum Hinzufügen von Eigenschaftsquellen zur Umgebung eingeführt. Diese Annotation ist in Verbindung mit der Java-basierten Konfiguration und der Annotation@Configurationzu verwenden:

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

Eine andere sehr nützliche Methode zum Registrieren einer neuen Eigenschaftendatei ist die Verwendung eines Platzhalters, mit dem Siedynamically select the right file at runtime eingeben können. beispielsweise:

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

2.1. Mehrere Eigenschaftenpositionen definieren

Die Annotation@PropertySource ist wiederholbaraccording to Java 8 conventions. Wenn wir Java 8 oder höher verwenden, können wir diese Anmerkung verwenden, um mehrere Eigenschaftenpositionen zu definieren:

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

Natürlich können wir auch die Annotation@PropertySources verwenden und ein Array von@PropertySource angeben. Dies funktioniert in jeder unterstützten Java-Version, nicht nur in Java 8 oder höher:

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

In beiden Fällen ist zu beachten, dassin the event of a property name collision, the last source read takes precedence.

3. Registrieren Sie eine Eigenschaftendatei in XML

In XML können Spring überthe <context:property-placeholder … > namespace element neue Eigenschaftendateien zugänglich gemacht werden:

Diefoo.properties-Datei sollte unter/src/main/resources platziert werden, damit sie zur Laufzeit im Klassenpfad verfügbar ist.

Fallsmultiple <property-placeholder> elements im Spring-Kontext vorhanden sind, gibt es einige empfohlene Best Practices:

  • Das Attributorder muss angegeben werden, um die Reihenfolge festzulegen, in der diese von Spring verarbeitet werden

  • Alle Eigenschaftsplatzhalter abzüglich der letzten (höchsteorder) solltenignore-unresolvable=”true” haben, damit der Auflösungsmechanismus im Kontext an andere weitergegeben werden kann, ohne eine Ausnahme auszulösen

3.1. Registrieren Sie mehrere Eigenschaftendateien in XML

Im vorherigen Abschnitt haben wir gesehen, wie mehrere Eigenschaftendateien mithilfe von Anmerkungen in Java 8 oder höher definiert werden. Ebenso können wirdefine multiple properties files using XML configuration:

Und nach wie vorin the event of a property name collision, the last source read takes precedence.

4. Verwenden / Injizieren von Eigenschaften

Injecting a property with the @Value annotation ist einfach:

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

A default value of the property kann auch angegeben werden:

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

Verwenden von Eigenschaften in der Spring XML-Konfiguration:


  

Sowohl die älterenPropertyPlaceholderConfigurer als auch die neuenPropertySourcesPlaceholderConfigurer wurden im Frühjahr 3,1resolve $\{…} placeholders innerhalb der Bean-Definitionseigenschaftswerte und der@Value-Annotationen hinzugefügt.

Schließlich - wir können obtain the value of a property using the Environment API:

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

Eine sehr wichtige Einschränkung hierbei ist, dassusing <property-placeholder> will not expose the properties to the Spring Environment - dies bedeutet, dass das Abrufen des solchen Werts nicht funktioniert -null zurückgibt:

env.getProperty("key.something")

5. Eigenschaften mit Spring Boot

Bevor wir uns mit erweiterten Konfigurationsoptionen für Eigenschaften befassen, sollten wir uns einige Zeit mitthe new properties support in Spring Boot befassen.

Im Allgemeinen umfasst diese neue Unterstützungless configuration im Vergleich zu Standard Spring, was natürlich eines der Hauptziele von Boot ist.

5.1. application.properties - die Standardeigenschaftendatei

Boot wendet seine typische Konvention gegenüber dem Konfigurationsansatz auf Eigenschaftendateien an. Dies bedeutet, dass wir einfach eine "application.properties" -Datei in unser "src/main/resources" -Verzeichnis einfügen können, die automatisch erkannt wird. Wir können dann wie gewohnt alle geladenen Eigenschaften daraus injizieren.

Wenn Sie diese Standarddatei verwenden, müssen Sie weder einPropertySourceexplizit registrieren noch einen Pfad zu einer Eigenschaftendatei angeben.

Wir können auch zur Laufzeit eine andere Datei konfigurieren, wenn wir eine Umgebungseigenschaft verwenden müssen:

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

5.2. Umgebungsspezifische Eigenschaftendatei

Wenn wir unterschiedliche Umgebungen ansprechen müssen, gibt es in Boot einen integrierten Mechanismus dafür.

Wir können einfach eine“application-environment.properties”-Datei im“src/main/resources”-Verzeichnis definieren und dann ein Spring-Profil mit demselben Umgebungsnamen festlegen.

Wenn wir beispielsweise eine "Staging" -Umgebung definieren, bedeutet dies, dass wir einstaging-Profil und dannapplication-staging.properties definieren müssen.

Diese env-Datei wird geladen undwill take precedence over the default property file. Beachten Sie, dass die Standarddatei weiterhin geladen wird. Bei einer Eigenschaftskollision hat nur die umgebungsspezifische Eigenschaftendatei Vorrang.

5.3. Testspezifische Eigenschaftendatei

Möglicherweise müssen wir auch andere Eigenschaftswerte verwenden, wenn unsere Anwendung getestet wird.

Spring Boot erledigt dies für uns, indem es während eines Testlaufs in unserem Verzeichnis "src/test/resources" nachschaut. Auch hier sind die Standardeigenschaften weiterhin wie gewohnt injizierbar, werden jedoch bei einer Kollision überschrieben.

5.4. Die Annotation@TestPropertySource

Wenn wir eine genauere Kontrolle über die Testeigenschaften benötigen, können wir die Annotation@TestPropertySourceverwenden.

Auf diese Weise können wir Testeigenschaften für einen bestimmten Testkontext festlegen und dabei Vorrang vor den Standardeigenschaftsquellen haben:

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

Wenn wir keine Datei verwenden möchten, können wir Namen und Werte direkt angeben:

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

Einen ähnlichen Effekt können wir auch mit dem Argumentpropertiesder Annotation@SpringBootTesterzielen:

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

5.5. Hierarchische Eigenschaften

Wenn wir Eigenschaften haben, die zusammen gruppiert sind, können wir die Annotation@ConfigurationPropertiesverwenden, die diese Eigenschaftshierarchien in Java-Objektdiagramme abbildet.

Nehmen wir einige Eigenschaften, die zum Konfigurieren einer Datenbankverbindung verwendet werden:

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

Verwenden Sie dann die Anmerkung, um sie einem Datenbankobjekt zuzuordnen:

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

    // standard getters and setters
}

Spring Boot wendet die Konvention über den Konfigurationsansatz erneut an und ordnet automatisch die Eigenschaftsnamen und die entsprechenden Felder zu. Alles, was wir liefern müssen, ist das Eigenschaftspräfix.

Wenn Sie sich eingehender mit Konfigurationseigenschaften befassen möchten, sehen Sie sichthe in-depth article an.

5.6. Alternative - YAML-Dateien

YAML-Dateien werden ebenfalls unterstützt.

Dieselben Namensregeln gelten für testspezifische, umgebungsspezifische und Standardeigenschaftendateien. Der einzige Unterschied besteht in der Dateierweiterung und einer Abhängigkeit von derSnakeYAML-Bibliothek, die sich in Ihrem Klassenpfad befindet.

YAML eignet sich besonders für die hierarchische Speicherung von Eigenschaften. die folgende Eigenschaftendatei:

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

Gehört auch zu folgender YAML-Datei:

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

Erwähnenswert ist auch, dass YAML-Dateien die Annotation@PropertySourcenicht unterstützen. Wenn also die Verwendung der Annotation erforderlich wäre, würden wir die Verwendung einer Eigenschaftendatei einschränken.

5.7. Eigenschaften aus Befehlszeilenargumenten

Im Gegensatz zur Verwendung von Dateien können Eigenschaften direkt in der Befehlszeile übergeben werden:

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

Sie können dies auch über Systemeigenschaften tun, die vor dem Befehl-jarund nicht danach bereitgestellt werden:

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

5.8. Eigenschaften aus Umgebungsvariablen

Spring Boot erkennt auch Umgebungsvariablen und behandelt sie als Eigenschaften:

export name=value
java -jar app.jar

5.9 Randomization of Property Values

Wenn wir keine deterministischen Eigenschaftswerte wollen, könnenRandomValuePropertySource verwendet werden, um die Werte von Eigenschaften zufällig zu sortieren:

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

5.10. Zusätzliche Arten von Eigenschaftsquellen

Spring Boot unterstützt eine Vielzahl von Eigenschaftenquellen und implementiert eine durchdachte Anordnung, um ein vernünftiges Überschreiben zu ermöglichen. Es lohnt sich, dieofficial documentation zu konsultieren, die über den Umfang dieses Artikels hinausgehen.

6. Konfiguration mit Raw Beans in Spring 3.0 -PropertyPlaceholderConfigurer

Neben den praktischen Methoden zum Abrufen von Eigenschaften in Spring - Annotationen und dem XML-Namespace - kann auch die Eigenschaftskonfigurations-Bean definiert undmanually registriert werden. Die Arbeit mitPropertyPlaceholderConfigurer gibt uns die volle Kontrolle über die Konfiguration, mit dem Nachteil, dass wir ausführlicher und meistens unnötig sind.

6.1. Java-Konfiguration

@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. XML-Konfiguration


    
        
            classpath:foo.properties
        
    
    

7. Konfiguration mit Rohbohnen im Frühjahr 3.1 -PropertySourcesPlaceholderConfigurer

In ähnlicher Weise können in Spring 3.1 die neuenPropertySourcesPlaceholderConfigurer auch manuell konfiguriert werden:

7.1. Java-Konfiguration

@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. XML-Konfiguration


    
        
            classpath:foo.properties
        
    
    

8. Eigenschaften in Eltern-Kind-Kontexten

Diese Frage taucht immer wieder auf - was passiert, wenn Ihreweb application has a parent and a child context? Der übergeordnete Kontext kann einige gemeinsame Kernfunktionen und Beans und dann einen (oder mehrere) untergeordnete Kontexte enthalten, die möglicherweise servletspezifische Beans enthalten.

Was ist in diesem Fall der beste Weg, um Eigenschaftendateien zu definieren und in diese Kontexte aufzunehmen? Was ist mehr - wie können diese Eigenschaften am besten aus Spring abgerufen werden? Hier ist die einfache Aufschlüsselung.

8.1. Wenn die Eigenschaftendatei in XML mit roperty-placeholder> definiert ist

Wenn die Dateidefined in the Parent context ist:

  • @Value funktioniert inChild context: NO

  • @Value funktioniert inParent context: JA

Wenn die Dateidefined in the Child context ist:

  • @Value funktioniert inChild context: JA

  • @Value funktioniert inParent context: NO

Schließlich setzen<property-placeholder>, wie bereits erwähnt, die Eigenschaften nicht der Umgebung aus.

  • environment.getProperty funktioniert ineither context: NO

8.2. Wenn die Eigenschaftendatei in Java mit@PropertySource definiert ist

Wenn die Dateidefined in the Parent context ist:

  • @Value funktioniert inChild context: JA

  • @Value funktioniert inParent context: JA

  • environment.getProperty inChild context: JA

  • environment.getProperty inParent context: JA

Wenn die Dateidefined in the Child context ist:

  • @Value funktioniert inChild context: JA

  • @Value funktioniert inParent context: NO

  • environment.getProperty inChild context: JA

  • environment.getProperty inParent context: NEIN

9. Fazit

Dieser Artikel zeigt mehrereexamples of working with properties and properties files in Spring.

Wie immer ist der gesamte Code, der den Artikel unterstützt,over on Github verfügbar. Dies ist ein Maven-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein.