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.
Konfigurieren Sie eine Spring Boot-Webanwendung
Einige der nützlicheren Konfigurationen für eine Spring Boot-Anwendung.
Anleitung zu @ConfigurationProperties in Spring Boot
Eine schnelle und praktische Anleitung für die @ ConfigurationProperties-Annotation in Spring Boot.
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.