it-swarm.com.de

Spring Boot und mehrere externe Konfigurationsdateien

Ich habe mehrere Eigenschaftendateien, die ich von Classpath laden möchte. Es gibt eine Voreinstellung unter /src/main/resources, die Teil von myapp.jar ist. Meine springcontext erwartet, dass sich Dateien im Klassenpfad befinden. d.h. 

<util:properties id="Job1Props"
    location="classpath:job1.properties"></util:properties>

<util:properties id="Job2Props"
    location="classpath:job2.properties"></util:properties>

Ich brauche auch die Option, diese Eigenschaften mit einem externen Set zu überschreiben. Ich habe einen externen Konfigurationsordner in cwd. Laut Spring Boot sollte sich der doc config-Ordner im Klassenpfad befinden. Aus doc ist jedoch nicht klar, ob es nur den applicaiton.properties oder alle Eigenschaften in config überschreibt. 

Wenn ich es getestet habe, wird nur application.properties abgeholt, und die restlichen Eigenschaften werden noch von /src/main/resources abgerufen. Ich habe versucht, sie als durch Kommas getrennte Liste an spring.config.location zu liefern, aber die Standardeinstellung wird immer noch nicht überschrieben.

Wie kann ich erreichen, dass mehrere externe Konfigurationsdateien die Standardeinstellungen überschreiben? 

Als Workaround habe ich derzeit app.config.location (App-spezifische Eigenschaft) verwendet, die ich über die Befehlszeile bereitstelle. d.h. 

Java -jar myapp.jar app.config.location=file:./config

und ich änderte meine applicationcontext in 

<util:properties id="Job2Props"
    location="{app.config.location}/job2.properties"></util:properties>

Und so trenne ich beim Laden von Application zwischen Datei und Klassenpfad. 
EDITS:

//psuedo code

if (StringUtils.isBlank(app.config.location)) {
            System.setProperty(APP_CONFIG_LOCATION, "classpath:");
}

Ich möchte die obige Problemumgehung wirklich nicht verwenden und habe alle externen Konfigurationsdateien des Klassenpfads im Frühling überschrieben, wie dies für die application.properties-Datei der Fall ist.

81
nir

Bei der Verwendung von Spring Boot werden die Eigenschaften in der folgenden Reihenfolge geladen (siehe Externalized Configuration im Spring Boot-Referenzhandbuch).

  1. Kommandozeilenargumente.
  2. Java-Systemeigenschaften (System.getProperties ()).
  3. Betriebssystemumgebungsvariablen.
  4. JNDI-Attribute von Java: comp/env
  5. Eine RandomValuePropertySource, die nur zufällige Eigenschaften hat. *.
  6. Anwendungseigenschaften außerhalb Ihres verpackten Glases (application.properties einschließlich YAML und Profilvarianten).
  7. In Ihrem jar verpackte Anwendungseigenschaften (application.properties einschließlich YAML und Profilvarianten).
  8. @PropertySource-Anmerkungen zu Ihren @ Configuration-Klassen.
  9. Standardeigenschaften (angegeben mit SpringApplication.setDefaultProperties).

Beim Auflösen von Eigenschaften (d. H. @Value("${myprop}")) erfolgt das Auflösen in umgekehrter Reihenfolge (also beginnend mit 9).

Zum Hinzufügen verschiedener Dateien können Sie die spring.config.location-Eigenschaften verwenden, die eine durch Kommas getrennte Liste von Eigenschaftsdateien oder Dateispeicherorten (Verzeichnissen) enthalten. 

-Dspring.config.location=your/config/dir/

Die oben genannte Liste fügt ein Verzeichnis hinzu, in dem application.properties-Dateien abgerufen werden.

-Dspring.config.location=classpath:job1.properties,classpath:job2.properties

Dadurch wird die 2 Eigenschaftendatei zu den Dateien hinzugefügt, die geladen werden. 

Die Standardkonfigurationsdateien und -speicherorte werden vor den zusätzlich angegebenen spring.config.location-Dateien geladen. Dies bedeutet, dass letztere immer die in den vorherigen festgelegten Eigenschaften überschreiben. (Siehe auch diesen Abschnitt des Spring Boot Reference Guide).

Wenn spring.config.location Verzeichnisse enthält (im Gegensatz zu Dateien), sollten sie mit/enden (und die Namen werden vor dem Laden mit spring.config.name erstellt). Der Standardsuchpfad classpath:,classpath:/config,file:,file:config/ wird unabhängig vom Wert von spring.config.location immer verwendet. Auf diese Weise können Sie Standardwerte für Ihre Anwendung in application.properties (oder einem beliebigen anderen Basisnamen, den Sie mit spring.config.name auswählen) festlegen und zur Laufzeit mit einer anderen Datei überschreiben, wobei die Standardeinstellungen beibehalten werden.

UPDATE: Das Verhalten von spring.config.location überschreibt jetzt den Standardwert, anstatt ihn hinzuzufügen. Sie müssen spring.config.additional-location verwenden, um die Standardeinstellungen beizubehalten. Dies ist eine Verhaltensänderung von 1.x zu 2.x

106
M. Deinum

Mit Spring boot funktioniert die spring.config.location einfach, indem Sie durch Kommas getrennte Eigenschaftendateien bereitstellen.

siehe den Code unten

@PropertySource(ignoreResourceNotFound=true,value="classpath:jdbc-${spring.profiles.active}.properties")
public class DBConfig{

     @Value("${jdbc.Host}")
        private String jdbcHostName;
     }
}

man kann die Standardversion von jdbc.properties in die Anwendung einfügen. Die externen Versionen können hier eingestellt werden.

Java -jar target/myapp.jar --spring.config.location=classpath:file:///C:/Apps/springtest/jdbc.properties,classpath:file:///C:/Apps/springtest/jdbc-dev.properties

Basierend auf dem Profilwert, der mit der Eigenschaft spring.profiles.active festgelegt wurde, wird der Wert von jdbc.Host abgerufen ..__ wann (unter Windows)

set spring.profiles.active=dev

jdbc.Host nimmt den Wert von jdbc-dev.properties an.

zum 

set spring.profiles.active=default

jdbc.Host nimmt den Wert von jdbc.properties an.

26
ganesh jadhav

Schauen Sie sich den PropertyPlaceholderConfigurer an, ich finde es klarer als Annotation zu verwenden.

z.B.

@Configuration
public class PropertiesConfiguration {


    @Bean
    public PropertyPlaceholderConfigurer properties() {
        final PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
//        ppc.setIgnoreUnresolvablePlaceholders(true);
        ppc.setIgnoreResourceNotFound(true);

        final List<Resource> resourceLst = new ArrayList<Resource>();

        resourceLst.add(new ClassPathResource("myapp_base.properties"));
        resourceLst.add(new FileSystemResource("/etc/myapp/overriding.propertie"));
        resourceLst.add(new ClassPathResource("myapp_test.properties"));
        resourceLst.add(new ClassPathResource("myapp_developer_overrides.properties")); // for Developer debugging.

        ppc.setLocations(resourceLst.toArray(new Resource[]{}));

        return ppc;
    }
20
user3206144

Spring Boot 1.X und Spring Boot 2.X bieten nicht die gleichen Optionen und Verhaltensweisen für Externalized Configuration .

Die sehr gute Antwort von M. Deinum bezieht sich auf Spring Boot 1-Spezifikationen.
Ich werde hier ein Update für Spring Boot 2 durchführen.

Quellen und Reihenfolge der Umgebungseigenschaften

Spring Boot 2 verwendet eine ganz bestimmte PropertySource Reihenfolge, die ein sinnvolles Überschreiben von Werten ermöglicht. Eigenschaften werden in der folgenden Reihenfolge berücksichtigt:

  • Eigenschaften der globalen Devtools-Einstellungen in Ihrem Ausgangsverzeichnis (~/.spring-boot-devtools.properties, wenn devtools aktiv ist).

  • @TestPropertySource Anmerkungen zu Ihren Tests.

  • Annotationsattribut @SpringBootTest#properties Für Ihre Tests. Kommandozeilenargumente.

  • Eigenschaften von SPRING_APPLICATION_JSON (Inline-JSON, eingebettet in eine Umgebungsvariable oder Systemeigenschaft).

  • ServletConfig init Parameter.

  • ServletContext init Parameter.

  • JNDI-Attribute von Java:comp/env.

  • Java-Systemeigenschaften (System.getProperties()).

  • Betriebssystem-Umgebungsvariablen.

  • Ein RandomValuePropertySource, dessen Eigenschaften nur zufällig sind. *.

  • Profilspezifische Anwendungseigenschaften außerhalb Ihres JAR-Pakets (application-{profile}.properties Und YAML-Varianten).

  • Profilspezifische Anwendungseigenschaften, die in Ihrer JAR-Datei enthalten sind (application-{profile}.properties Und YAML-Varianten).

  • Anwendungseigenschaften außerhalb Ihres verpackten Glases (application.properties Und YAML-Varianten).

  • Anwendungseigenschaften, die in Ihrem Jar gepackt sind (application.properties Und YAML-Varianten).

  • @PropertySource - Anmerkungen zu Ihren @Configuration - Klassen. Standardeigenschaften (festgelegt durch Setzen von SpringApplication.setDefaultProperties).

Um externe Eigenschaftendateien anzugeben, sollten diese Optionen Sie interessieren:

  • Profilspezifische Anwendungseigenschaften außerhalb Ihres JAR-Pakets (application-{profile}.properties Und YAML-Varianten).

  • Anwendungseigenschaften außerhalb Ihres verpackten Glases (application.properties Und YAML-Varianten).

  • @PropertySource - Anmerkungen zu Ihren @Configuration - Klassen. Standardeigenschaften (festgelegt durch Setzen von SpringApplication.setDefaultProperties).

Sie können nur eine dieser 3 Optionen verwenden oder sie gemäß Ihren Anforderungen kombinieren.
Zum Beispiel ist es für sehr einfache Fälle ausreichend, nur profilspezifische Eigenschaften zu verwenden. In anderen Fällen möchten Sie möglicherweise sowohl profilspezifische Eigenschaften als auch Standardeigenschaften und @PropertySource Verwenden.

Standardspeicherorte für application.properties-Dateien

Über application.properties - Dateien (und Varianten) lädt Spring sie standardmäßig und fügt ihre Eigenschaften in der Umgebung in der folgenden Reihenfolge hinzu:

  • Ein/config-Unterverzeichnis des aktuellen Verzeichnisses

  • Das aktuelle Verzeichnis

  • Ein classpath/config-Paket

  • Die Klassenpfadwurzel

Die höheren Prioritäten sind so wörtlich:
classpath:/,classpath:/config/,file:./,file:./config/.

Wie werden Eigenschaftendateien mit bestimmten Namen verwendet?

Die Standardspeicherorte reichen nicht immer aus: Die Standardspeicherorte wie der Standarddateiname (application.properties) Passen möglicherweise nicht. Außerdem müssen Sie wie in der OP-Frage möglicherweise mehrere andere Konfigurationsdateien als application.properties (Und Variante) angeben.
Also wird spring.config.name Nicht ausreichen.

In diesem Fall sollten Sie einen expliziten Speicherort angeben, indem Sie die Umgebungseigenschaft spring.config.location Verwenden (eine durch Kommas getrennte Liste von Verzeichnispositionen oder Dateipfaden).
Um frei über das Dateinamenmuster zu sein, ziehen Sie die Liste der Dateipfade der Liste der Verzeichnisse vor.
So zum Beispiel:

Java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties

Auf diese Weise ist es am ausführlichsten, nur den Ordner anzugeben, aber es ist auch die Möglichkeit, unsere Konfigurationsdateien sehr genau anzugeben und die effektiv verwendeten Eigenschaften klar zu dokumentieren.

spring.config.location ersetzt jetzt Standardspeicherorte, anstatt sie zu ergänzen

Mit Spring Boot 1 werden mit dem Argument spring.config.location Bestimmte Positionen in der Spring-Umgebung hinzugefügt.
Ab Spring Boot 2 ersetzt spring.config.location Die von Spring verwendeten Standardspeicherorte durch die angegebenen Speicherorte in der Spring-Umgebung, wie angegeben in der Dokumentation .

Wenn benutzerdefinierte Konfigurationspfade mit spring.config.location Konfiguriert werden, ersetzen sie die Standardpfade. Wenn beispielsweise spring.config.location Mit dem Wert classpath:/custom-config/, file:./custom-config/ Konfiguriert ist, lautet die Suchreihenfolge wie folgt:

  1. file:./custom-config/

  2. classpath:custom-config/

Mit spring.config.location Kann jetzt sichergestellt werden, dass alle application.properties - Dateien explizit angegeben werden.
Für über JARs, die keine application.properties - Dateien packen sollen, ist das ziemlich nett.

Um das alte Verhalten von spring.config.location Während der Verwendung von Spring Boot 2 beizubehalten, können Sie die neue Eigenschaft spring.config.additional-location Anstelle von spring.config.location Verwenden, die weiterhin die Speicherorte wie von der angegeben Dokumentation :

Wenn benutzerdefinierte Konfigurationspfade mit spring.config.additional-location Konfiguriert werden, werden sie alternativ zusätzlich zu den Standardpfaden verwendet.


In der Praxis

Nehmen wir also an, dass Sie wie in der OP-Frage zwei externe Eigenschaftendateien angeben müssen und eine Eigenschaftendatei im uber-Jar enthalten ist.

So verwenden Sie nur die von Ihnen angegebenen Konfigurationsdateien:

-Dspring.config.location=classpath:/job1.properties,classpath:/job2.properties,classpath:/applications.properties   

So fügen Sie diesen Konfigurationsdateien an den Standardpositionen hinzu:

-Dspring.config.additional-location=classpath:/job1.properties,classpath:/job2.properties

classpath:/applications.properties Ist im letzten Beispiel nicht erforderlich, da die Standardspeicherorte dies haben und die Standardspeicherorte hier nicht überschrieben, sondern erweitert werden.

17
davidxxx

Ich hatte das gleiche Problem. Ich wollte die Möglichkeit haben, eine interne Konfigurationsdatei beim Start mit einer externen Datei zu überschreiben, ähnlich wie bei der Erkennung von Spring Boot application.properties. In meinem Fall handelt es sich um eine user.properties-Datei, in der meine Anwendungsbenutzer gespeichert sind.

Meine Anforderungen:

Laden Sie die Datei von den folgenden Speicherorten (in dieser Reihenfolge)

  1. Der Klassenpfad
  2. Ein / config -Unterverzeichnis des aktuellen Verzeichnisses. 
  3. Das aktuelle Verzeichnis
  4. Vom Verzeichnis oder einem Dateispeicherort, der beim Start durch einen Befehlszeilenparameter angegeben wird

Ich habe folgende Lösung gefunden:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.PathResource;
import org.springframework.core.io.Resource;

import Java.io.IOException;
import Java.util.Properties;

import static Java.util.Arrays.stream;

@Configuration
public class PropertiesConfig {

    private static final Logger LOG = LoggerFactory.getLogger(PropertiesConfig.class);

    private final static String PROPERTIES_FILENAME = "user.properties";

    @Value("${properties.location:}")
    private String propertiesLocation;

    @Bean
    Properties userProperties() throws IOException {
        final Resource[] possiblePropertiesResources = {
                new ClassPathResource(PROPERTIES_FILENAME),
                new PathResource("config/" + PROPERTIES_FILENAME),
                new PathResource(PROPERTIES_FILENAME),
                new PathResource(getCustomPath())
        };
        // Find the last existing properties location to emulate spring boot application.properties discovery
        final Resource propertiesResource = stream(possiblePropertiesResources)
                .filter(Resource::exists)
                .reduce((previous, current) -> current)
                .get();
        final Properties userProperties = new Properties();

        userProperties.load(propertiesResource.getInputStream());

        LOG.info("Using {} as user resource", propertiesResource);

        return userProperties;
    }

    private String getCustomPath() {
        return propertiesLocation.endsWith(".properties") ? propertiesLocation : propertiesLocation + PROPERTIES_FILENAME;
    }

}

Jetzt verwendet die Anwendung die Classpath-Ressource, sucht jedoch auch an den anderen angegebenen Orten nach einer Ressource. Die letzte vorhandene Ressource wird ausgewählt und verwendet. Ich kann meine App mit Java -jar myapp.jar --properties.location =/directory/myproperties.properties starten, um eine Eigenschaftsposition zu verwenden, die mein Boot schwimmt .

Ein wichtiges Detail hier: Verwenden Sie einen leeren String als Standardwert für die Eigenschaft properties.location in der Annotation @Value, um Fehler zu vermeiden, wenn die Eigenschaft nicht festgelegt ist. 

Die Konvention für eine properties.location lautet: Verwenden Sie ein Verzeichnis oder einen Pfad zu einer Properties-Datei als properties.location.

Wenn Sie nur bestimmte Eigenschaften überschreiben möchten, kann eine PropertiesFactoryBean mit setIgnoreResourceNotFound (true) verwendet werden, wobei das Ressourcenarray als Speicherorte festgelegt ist.

Ich bin mir sicher, dass diese Lösung für mehrere Dateien erweitert werden kann ...

EDIT

Hier meine Lösung für mehrere Dateien :) Wie zuvor kann dies mit einer PropertiesFactoryBean kombiniert werden.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.PathResource;
import org.springframework.core.io.Resource;

import Java.io.IOException;
import Java.util.Map;
import Java.util.Properties;

import static Java.util.Arrays.stream;
import static Java.util.stream.Collectors.toMap;

@Configuration
class PropertiesConfig {

    private final static Logger LOG = LoggerFactory.getLogger(PropertiesConfig.class);
    private final static String[] PROPERTIES_FILENAMES = {"job1.properties", "job2.properties", "job3.properties"};

    @Value("${properties.location:}")
    private String propertiesLocation;

    @Bean
    Map<String, Properties> myProperties() {
        return stream(PROPERTIES_FILENAMES)
                .collect(toMap(filename -> filename, this::loadProperties));
    }

    private Properties loadProperties(final String filename) {
        final Resource[] possiblePropertiesResources = {
                new ClassPathResource(filename),
                new PathResource("config/" + filename),
                new PathResource(filename),
                new PathResource(getCustomPath(filename))
        };
        final Resource resource = stream(possiblePropertiesResources)
                .filter(Resource::exists)
                .reduce((previous, current) -> current)
                .get();
        final Properties properties = new Properties();

        try {
            properties.load(resource.getInputStream());
        } catch(final IOException exception) {
            throw new RuntimeException(exception);
        }

        LOG.info("Using {} as user resource", resource);

        return properties;
    }

    private String getCustomPath(final String filename) {
        return propertiesLocation.endsWith(".properties") ? propertiesLocation : propertiesLocation + filename;
    }

}
6
mxsb

mit Spring Boot können wir unterschiedliche Profile für unterschiedliche Umgebungen schreiben. Beispielsweise können wir separate Eigenschaftendateien für Produktions-, QA- und lokale Umgebungen haben

die Datei "application-local.properties" mit Konfigurationen für meinen lokalen Computer ist

spring.profiles.active=local

spring.data.mongodb.Host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=users
spring.data.mongodb.username=humble_freak
spring.data.mongodb.password=freakone

spring.rabbitmq.Host=localhost
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.port=5672

rabbitmq.publish=true

Ebenso können wir application-prod.properties und application-qa.properties beliebig viele Eigenschaftsdateien schreiben

schreiben Sie dann einige Skripts, um die Anwendung für verschiedene Umgebungen zu starten, z.

mvn spring-boot:run -Drun.profiles=local
mvn spring-boot:run -Drun.profiles=qa
mvn spring-boot:run -Drun.profiles=prod
6
Humble Freak

dies ist ein einfacher Ansatz, der Federstiefel verwendet

TestClass.Java

@Configuration
@Profile("one")
@PropertySource("file:/{selected location}/app.properties")
public class TestClass {

    @Autowired
    Environment env;

    @Bean
    public boolean test() {
        System.out.println(env.getProperty("test.one"));
        return true;
    }
}

der app.properties-Kontext an Ihrem ausgewählten Ort

test.one = 1234

ihr Spring Boot-Anwendung 

@SpringBootApplication

public class TestApplication {

    public static void main(String[] args) {
        SpringApplication.run(testApplication.class, args);
    }
}

und den vordefinierten application.properties context

spring.profiles.active = one

sie können beliebig viele Konfigurationsklassen schreiben und aktivieren/deaktivieren, indem Sie spring.profiles.active = den Profilnamen/die Profilnamen {durch Kommata getrennt} setzen.

wie Sie sehen können, ist Spring Boot großartig, es braucht nur etwas Zeit, um sich mit Ihnen vertraut zu machen. Erwähnenswert ist, dass Sie @Value auch auf Ihren Feldern verwenden können

@Value("${test.one}")
String str;
5
Farzan Skt

Ich hatte gerade ein ähnliches Problem und habe die Ursache herausgefunden: Die Datei application.properties hatte falsche Besitz- und Rwx-Attribute. Beim Starten von Tomcat befand sich die Datei application.properties am richtigen Ort, aber im Besitz eines anderen Benutzers:

$ chmod 766 application.properties

$ chown Tomcat application.properties
5
robjwilkins

Eine modifizierte Version der @mxsb-Lösung, mit der mehrere Dateien definiert werden können. In meinem Fall handelt es sich um Yml-Dateien.

In meinem application-dev.yml habe ich diese config hinzugefügt, die es mir ermöglicht, alle yml-Dateien einzubinden, die -dev.yml enthalten. Dies kann auch eine Liste bestimmter Dateien sein. "" Klassenpfad: /test/test.yml,classpath: /test2/test.yml "

application:
  properties:
    locations: "classpath*:/**/*-dev.yml"

Dies hilft, eine Eigenschaftskarte zu erhalten.

@Configuration

public class PropertiesConfig {

private final static Logger LOG = LoggerFactory.getLogger(PropertiesConfig.class);

@Value("${application.properties.locations}")
private String[] locations;

@Autowired
private ResourceLoader rl;

@Bean
Map<String, Properties> myProperties() {
    return stream(locations)
            .collect(toMap(filename -> filename, this::loadProperties));
}

private Properties loadProperties(final String filename) {

    YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
    try {
        final Resource[] possiblePropertiesResources = ResourcePatternUtils.getResourcePatternResolver(rl).getResources(filename);
        final Properties properties = new Properties();
        stream(possiblePropertiesResources)
                .filter(Resource::exists)
                .map(resource1 -> {
                    try {
                        return loader.load(resource1.getFilename(), resource1);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }).flatMap(l -> l.stream())
                .forEach(propertySource -> {
                    Map source = ((MapPropertySource) propertySource).getSource();
                    properties.putAll(source);
                });

        return properties;
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
}

Wenn ich jedoch, wie in meinem Fall, die Yml-Dateien für jedes Profil aufteilen und laden und vor der Beans-Initialisierung direkt in die Federkonfiguration einfügen wollte. 

config
    - application.yml
    - application-dev.yml
    - application-prod.yml
management
    - management-dev.yml
    - management-prod.yml

... Du hast die Idee

Die Komponente ist etwas anders

@Component
public class PropertiesConfigurer extends     PropertySourcesPlaceholderConfigurer
    implements EnvironmentAware, InitializingBean {

private final static Logger LOG = LoggerFactory.getLogger(PropertiesConfigurer.class);

private String[] locations;

@Autowired
private ResourceLoader rl;
private Environment environment;

@Override
public void setEnvironment(Environment environment) {
    // save off Environment for later use
    this.environment = environment;
    super.setEnvironment(environment);
}

@Override
public void afterPropertiesSet() throws Exception {
    // Copy property sources to Environment
    MutablePropertySources envPropSources = ((ConfigurableEnvironment) environment).getPropertySources();
    envPropSources.forEach(propertySource -> {
        if (propertySource.containsProperty("application.properties.locations")) {
            locations = ((String) propertySource.getProperty("application.properties.locations")).split(",");
            stream(locations).forEach(filename -> loadProperties(filename).forEach(source ->{
                envPropSources.addFirst(source);
            }));
        }
    });
}


private List<PropertySource> loadProperties(final String filename) {
    YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
    try {
        final Resource[] possiblePropertiesResources = ResourcePatternUtils.getResourcePatternResolver(rl).getResources(filename);
        final Properties properties = new Properties();
        return stream(possiblePropertiesResources)
                .filter(Resource::exists)
                .map(resource1 -> {
                    try {
                        return loader.load(resource1.getFilename(), resource1);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }).flatMap(l -> l.stream())
                .collect(Collectors.toList());
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

}

0
Codewarrior

Ich habe festgestellt, dass dies ein nützliches Muster ist, um zu folgen:

@RunWith(SpringRunner)
@SpringBootTest(classes = [ TestConfiguration, MyApplication ],
        properties = [
                "spring.config.name=application-MyTest_LowerImportance,application-MyTest_MostImportant"
                ,"debug=true", "trace=true"
        ]
)

Hier überschreiben wir die Verwendung von "application.yml", um "application-MyTest_LowerImportance.yml" und auch "application-MyTest_MostImportant.yml" zu verwenden.
(Spring sucht auch nach .properties-Dateien) 

Als zusätzlicher Bonus sind außerdem die Debug- und Trace-Einstellungen in einer separaten Zeile enthalten, sodass Sie sie bei Bedarf auskommentieren können.] 

Debug/Trace sind unglaublich nützlich, da Spring die Namen aller geladenen Dateien und der geladenen Dateien speichert.
Sie sehen zur Laufzeit solche Zeilen in der Konsole:

TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_MostImportant.properties' (file:./config/application-MyTest_MostImportant.properties) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_MostImportant.xml' (file:./config/application-MyTest_MostImportant.xml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_MostImportant.yml' (file:./config/application-MyTest_MostImportant.yml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_MostImportant.yaml' (file:./config/application-MyTest_MostImportant.yaml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_LowerImportance.properties' (file:./config/application-MyTest_LowerImportance.properties) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_LowerImportance.xml' (file:./config/application-MyTest_LowerImportance.xml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_LowerImportance.yml' (file:./config/application-MyTest_LowerImportance.yml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_LowerImportance.yaml' (file:./config/application-MyTest_LowerImportance.yaml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application-MyTest_MostImportant.properties' (file:./application-MyTest_MostImportant.properties) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application-MyTest_MostImportant.xml' (file:./application-MyTest_MostImportant.xml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application-MyTest_MostImportant.yml' (file:./application-MyTest_MostImportant.yml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application-MyTest_MostImportant.yaml' (file:./application-MyTest_MostImportant.yaml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application-MyTest_LowerImportance.properties' (file:./application-MyTest_LowerImportance.properties) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application-MyTest_LowerImportance.xml' (file:./application-MyTest_LowerImportance.xml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application-MyTest_LowerImportance.yml' (file:./application-MyTest_LowerImportance.yml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application-MyTest_LowerImportance.yaml' (file:./application-MyTest_LowerImportance.yaml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application-MyTest_MostImportant.properties' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application-MyTest_MostImportant.xml' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application-MyTest_MostImportant.yml' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application-MyTest_MostImportant.yaml' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application-MyTest_LowerImportance.properties' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application-MyTest_LowerImportance.xml' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application-MyTest_LowerImportance.yml' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application-MyTest_LowerImportance.yaml' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/application-MyTest_MostImportant.properties' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/application-MyTest_MostImportant.xml' resource not found
DEBUG 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Loaded config file 'file:/Users/xxx/dev/myproject/target/test-classes/application-MyTest_MostImportant.yml' (classpath:/application-MyTest_MostImportant.yml)
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/application-MyTest_MostImportant.yaml' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/application-MyTest_LowerImportance.properties' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/application-MyTest_LowerImportance.xml' resource not found
DEBUG 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Loaded config file 'file:/Users/xxx/dev/myproject/target/test-classes/application-MyTest_LowerImportance.yml' (classpath:/application-MyTest_LowerImportance.yml)
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/application-MyTest_LowerImportance.yaml' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_MostImportant-test.properties' (file:./config/application-MyTest_MostImportant-test.properties) resource not found
0
davidfrancis

Wenn Sie die in Ihrer application.properties-Datei angegebenen Werte überschreiben möchten, können Sie Ihr aktives Profil ändern, während Sie Ihre Anwendung ausführen, und eine Anwendungseigenschaftendatei für das Profil erstellen. Geben Sie beispielsweise das aktive Profil "override" an. Wenn Sie Ihre neue Anwendungseigenschaftendatei "application-override.properties" unter/tmp erstellt haben, können Sie sie dann ausführen

Java -jar yourApp.jar --spring.profiles.active="override" --spring.config.location="file:/tmp/,classpath:/" 

Die unter spring.config.location angegebenen Werte werden in umgekehrter Reihenfolge ausgewertet. In meinem Beispiel wird also zuerst das classpat ausgewertet, dann der Wert der Datei.

Wenn sich die JAR-Datei und die Datei "application-override.properties" im aktuellen Verzeichnis befinden, können Sie sie tatsächlich verwenden

Java -jar yourApp.jar --spring.profiles.active="override"

da Spring Boot die Eigenschaftsdatei für Sie findet

0
acaruci