Spring Bootと複数の外部構成ファイル


125

クラスパスからロードしたい複数のプロパティファイルがあります。の/src/main/resources一部であるデフォルトセットが1つありますmyapp.jar。私springcontextはファイルがクラスパス上にあることを期待しています。すなわち

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

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

これらのプロパティを外部セットでオーバーライドするオプションも必要です。に外部設定フォルダがありcwdます。春のブートごとに、doc構成フォルダーがクラスパス上にある必要があります。しかし、applicaiton.propertiesそこから、またはconfigのすべてのプロパティのみをオーバーライドする場合は、ドキュメントからは明確ではありません。

私がそれをテストしたとき、application.properties取得されるだけで、残りのプロパティは依然としてから取得され/src/main/resourcesます。私はそれらをコンマ区切りのリストとして提供しようとしましたspring.config.locationが、デフォルトのセットはまだオーバーライドされていません。

複数の外部構成ファイルでデフォルトのファイルを上書きするにはどうすればよいですか?

回避策として、私は現在app.config.location、コマンドラインから提供する(アプリ固有のプロパティ)を使用しています。すなわち

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

そして私はに変更applicationcontextしました

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

そして、これがアプリケーションのロード中にファイルとクラスパスを分離する方法です。
編集:

//psuedo code

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

上記の回避策を使用せずに、application.propertiesファイルに対して行うように、クラスパス上のすべての外部構成ファイルをSpringでオーバーライドしたいのですが。


4
application.propertiesいつも、ロードされspring.config.location、ファイルがチェックされ、追加の設定場所を追加することができます(それはで終わるときには/、あなたがそれらがロードされるファイルにあったポイントにカンマ区切りリストを置くしかし場合)。これは、こちらの
M. Deinum

回答:


154

Spring Bootを使用する場合、プロパティは次の順序で読み込まれます(Spring Bootリファレンスガイドの「外部化された構成」を参照)。

  1. コマンドライン引数。
  2. Javaシステムプロパティ(System.getProperties())。
  3. OS環境変数。
  4. java:comp / envのJNDI属性
  5. random。*内のプロパティのみを持つRandomValuePropertySource。
  6. パッケージ化されたjar外のアプリケーションプロパティ(YAMLおよびプロファイルバリアントを含むapplication.properties)。
  7. jar内にパッケージ化されたアプリケーションプロパティ(YAMLおよびプロファイルバリアントを含むapplication.properties)。
  8. @Configurationクラスの@PropertySourceアノテーション。
  9. デフォルトプロパティ(SpringApplication.setDefaultPropertiesを使用して指定)。

プロパティを解決するとき(つまり、@Value("${myprop}")解決は逆の順序で行われる(つまり、9から始まる)。

さまざまなファイルを追加するにspring.config.locationは、プロパティファイルまたはファイルの場所(ディレクトリ)のコンマ区切りリストを取得するプロパティを使用できます。

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

上記のものは、application.propertiesファイルを調べるディレクトリを追加します。

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

これにより、読み込まれたファイルに2つのプロパティファイルが追加されます。

デフォルトの構成ファイルと場所は、追加で指定されたspring.config.locationものの前にロードされます。これは、後者が常に前のファイルで設定されたプロパティをオーバーライドすることを意味します。(「Spring Boot Reference Guide」のこのセクションも参照してください)。

spring.config.location(ファイルではなく)ディレクトリが含まれている場合は、/で終わる必要があります(spring.config.nameロードされる前に生成された名前が追加されます)。の値classpath:,classpath:/config,file:,file:config/に関係なく、デフォルトの検索パスが常に使用されますspring.config.location。このようにして、アプリケーションのデフォルト値application.properties(または、で選択した他のベース名spring.config.name)を設定し、実行時に別のファイルでオーバーライドして、デフォルトを維持できます。

更新:spring.config.locationの動作は、デフォルトに追加する代わりにデフォルトをオーバーライドするようになりました。デフォルトを維持するには、spring.config.additional-locationを使用する必要があります。これは1.xから2.xへの動作の変更です


2
ありがとうございます。しかし、私はすでにこのリファレンスドキュメントを読んでおり、次の説明は混乱を招きます。「-Dspring.config.location = your / config / dir /上記のものは、application.propertiesファイルを参照するディレクトリを追加します。」application.propertiesファイルの意味は何ですか。それはただ一つのファイルです。いずれにしても、最後に「/」を付けてディレクトリ全体を取得できる場合は、それぞれをコンマ区切りのリストとして指定する必要はありません。私は私の記事で述べたが、私はそれを与えるだろうと私は両方のアプローチを試してみましたと思う1以上試す
NIR

ドキュメントに記載されているようにそれがために、他のデフォルトの場所のように相談する選択されますapplication.propertiesapplication-[env].properties。他のプロパティファイルは考慮されません。これはリファレンスガイドにも記載されています(リンクがつながるセクションとリファレンスガイドからの引用)。
M. Deinum 2014

1
はい、しかしそれは私には意味がありません。なぜディレクトリ全体ではなくクラスパス上のディレクトリから1種類のファイルのみを考慮するのですか?そのため、1つのプロパティファイルのみを使用する必要がありますが、これは良い方法ではありません。tomcatのように、特定のディレクトリ(およびその中にあるすべてのもの)をクラスパスに置くようにcommon.loaderを構成できます。
2014

3
ドキュメントの引用は役に立ちません。ドキュメントが明確である場合(十分ですか?特に必要な方法で?)、質問は必要ありません。たとえば、この場合、方法config.locationconfig.names相互作用は明確ではありませんが、相互作用の方法をすでに知っている人には明らかなようです。回答を更新してドキュメントに何かを追加できますか?
Narfanator 2018

13
の動作はspring.config.locationデフォルトに追加する代わりにデフォルトをオーバーライドするため、これを更新する必要があります。spring.config.additional-locationデフォルトを維持するにはを使用する必要があります。これは、1.xから2.xへの動作の変更です。
ロビン

32

Springブートでは、spring.config.locationは機能します。カンマ区切りのプロパティファイルを指定するだけです。

以下のコードを参照してください

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

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

デフォルトのバージョンのjdbc.propertiesをアプリケーション内に配置できます。これに外付けバージョンを設定できます。

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

spring.profiles.activeプロパティを使用して設定されたプロファイル値に基づいて、jdbc.hostの値が取得されます。だから(Windows上で)

set spring.profiles.active=dev

jdbc.hostはjdbc-dev.propertiesから値を取得します。

ために

set spring.profiles.active=default

jdbc.hostはjdbc.propertiesから値を取得します。


最初のコードブロックが機能するとは思わない。私はこれに自分を突き刺して、この答えに従いまし。まともな説明については、回答で参照されているjira.springsource.org/browse/SPR-8539を参照してください。
Sowka

27

Spring Boot 1.XとSpring Boot 2.Xは、について同じオプションと動作を提供しませんExternalized Configuration

M. Deinumの非常に良い答えは、Spring Boot 1の仕様を参照しています。
ここでSpring Boot 2に更新します。

環境プロパティのソースと順序

Spring Boot 2は、PropertySource値を適切に上書きできるように設計された非常に特殊な順序を使用します。プロパティは次の順序で考慮されます。

  • ホームディレクトリのDevtoolsグローバル設定プロパティ(devtoolsがアクティブな場合は〜/ .spring-boot-devtools.properties)。

  • @TestPropertySource テストの注釈。

  • @SpringBootTest#propertiesテストのアノテーション属性。コマンドライン引数。

  • [プロパティSPRING_APPLICATION_JSON(環境変数またはシステムプロパティに埋め込まれたインラインJSON)。

  • ServletConfig initパラメータ。

  • ServletContext initパラメータ。

  • のJNDI属性java:comp/env

  • Javaシステムプロパティ(System.getProperties())。

  • OS環境変数。

  • RandomValuePropertySourceランダムにのみプロパティを持つA。*。

  • パッケージ化されたjar(application-{profile}.propertiesおよびYAMLバリアント)外のプロファイル固有のアプリケーションプロパティ。

  • jar(application-{profile}.propertiesおよびYAMLバリアント)内にパッケージ化されたプロファイル固有のアプリケーションプロパティ。

  • パッケージ化されたjar(application.propertiesおよびYAMLバリアント)外のアプリケーションプロパティ。

  • jar(application.propertiesおよびYAMLバリアント)内にパッケージ化されたアプリケーションプロパティ。

  • @PropertySource@Configurationクラスの注釈。デフォルトのプロパティ(で設定 SpringApplication.setDefaultProperties)。

外部プロパティファイルを指定するには、これらのオプションが必要です。

  • パッケージ化されたjar(application-{profile}.propertiesおよびYAMLバリアント)外のプロファイル固有のアプリケーションプロパティ。

  • パッケージ化されたjar(application.propertiesおよびYAMLバリアント)外のアプリケーションプロパティ。

  • @PropertySource@Configurationクラスの注釈。デフォルトのプロパティ(で設定 SpringApplication.setDefaultProperties)。

これら3つのオプションのうち1つだけを使用するか、要件に応じてそれらを組み合わせることができます。
たとえば、プロファイル固有のプロパティのみを使用する非常に単純なケースでは十分ですが、他のケースでは、プロファイル固有のプロパティ、デフォルトプロパティ、および@PropertySource

application.propertiesファイルのデフォルトの場所

application.propertiesファイル(およびバリアント)については、デフォルトで、Springがファイルをロードし、以下の順序でこれらのプロパティを環境に追加します。

  • 現在のディレクトリの/ configサブディレクトリ

  • 現在のディレクトリ

  • クラスパス/ configパッケージ

  • クラスパスルート

優先順位が高いほど、文字通りです
classpath:/,classpath:/config/,file:./,file:./config/

特定の名前を持つプロパティファイルの使用方法

デフォルトの場所では必ずしも十分でapplication.propertiesはありません。デフォルトのファイル名()などのデフォルトの場所は適さない場合があります。さらに、OPの質問と同様に、application.properties(およびバリアント)以外の複数の構成ファイルを指定する必要がある場合があります。
だからspring.config.name十分ではありません。

この場合は、spring.config.location環境プロパティ(ディレクトリの場所またはファイルパスのコンマ区切りのリスト)を使用して、明示的な場所を指定する必要があります。
ファイル名のパターンを自由にするために、ディレクトリのリストよりもファイルパスのリストを優先します。
たとえば、次のようにします。

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

この方法は、フォルダーを指定するだけで最も冗長ですが、構成ファイルを非常に細かく指定し、効果的に使用されるプロパティを明確に文書化する方法でもあります。

spring.config.locationがデフォルトの場所に追加するのではなく、置き換える

Spring Boot 1では、spring.config.location引数はSpring環境の指定された場所を追加します。
ただし、Spring Boot 2以降でspring.config.location、ドキュメントで説明されているように、 Springで使用されるデフォルトの場所が、Spring環境の指定された場所に置き換えられます

を使用してカスタム構成の場所を構成すると spring.config.location、デフォルトの場所が置き換えられます。たとえばspring.config.location、に値classpath:/custom-config/、が設定されている場合 、file:./custom-config/検索順序は次のようになります。

  1. file:./custom-config/

  2. classpath:custom-config/

spring.config.location現在は、すべてのapplication.propertiesファイルを明示的に指定する必要があることを確認する方法です。ファイル
をパッケージ化application.propertiesすることを想定していないuber JARの場合、これはかなり良い方法です。

spring.config.locationSpring Boot 2を使用している間の古い動作を維持するspring.config.additional-locationにはspring.config.location、代わりに新しいプロパティを使用して、ドキュメントに記載されている場所追加できます

または、カスタム構成の場所がを使用して構成されて spring.config.additional-locationいる場合、デフォルトの場所に加えて使用されます。


実際には

OPの質問のように、指定する2つの外部プロパティファイルと、uber jarに含まれる1つのプロパティファイルがあるとします。

指定した構成ファイルのみを使用するには:

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

デフォルトの場所でこれらに構成ファイルを追加するには、次のようにします。

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

classpath:/applications.properties 最後の例では、デフォルトの場所にそれがあり、そのデフォルトの場所は上書きされず拡張されているため、必要ありません。


「classpath:/job1.properties」を指定しただけの場合、Springはディスク上の外部設定job1.propertiesをどこで見つけますか?ここで、クラスパスに外部プロパティを含むディレクトリをどのように追加しましたか?
トリスタン

@Tristanは基本的に、application.propertiesすべてのパラメーターを持つ1つと${file_name}.properties、部分的に定義されたプロパティセットを持つ複数のパラメーターを読み取ることができます。そのため、@PropertySourceファイルへの強いリンクまたは他の強力なリンクを使用している場合は、他の外部ファイルを作成し、そのプロパティをオーバーライドできます(例:from classpath:file.properties)。
Mister_Jesus

23

PropertyPlaceholderConfigurerを見てください。アノテーションよりも使用する方がわかりやすいと思います。

例えば

@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;
    }

この回答をありがとうございました。ベースXMLファイルを使用せずに、さまざまなXML構成のようなプロジェクトで同じことをどのように達成できるか教えていただけませんか?上記のあなたの答えは、注釈に基づく他のプロジェクトで私を助けました。再度ありがとうございます。
チェタン

8

これは、スプリングブーツを使用した1つの簡単なアプローチです。

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;
    }
}

選択した場所app.propertiesコンテキスト

test.one = 1234

あなたの春のブートアプリケーション

@SpringBootApplication

public class TestApplication {

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

および事前定義されたapplication.propertiesコンテキスト

spring.profiles.active = one

spring.profiles.active =プロファイル名/名前を設定するだけで、好きなだけ多くの設定クラスを記述し、それらを有効/無効にすることができます{コンマで区切られた}

春のブーツは素晴らしいので、慣れるには時間が必要です。フィールドで@Valueを使用することもできます。

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

7

私も同じ問題を抱えていました。Spring Bootのapplication.propertiesの検出と同様に、起動時に内部構成ファイルを外部ファイルで上書きする機能が必要でした。私の場合は、アプリケーションのユーザーが格納されているuser.propertiesファイルです。

私の要件:

次の場所からファイルをロードします(この順序で)

  1. クラスパス
  2. A / configのサブディレクトリカレントディレクトリの。
  3. 現在のディレクトリ
  4. 起動時にコマンドラインパラメータで指定されたディレクトリまたはファイルの場所から

私は次の解決策を思いつきました:

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;
    }

}

これで、アプリケーションはクラスパスリソースを使用しますが、指定された他の場所でもリソースをチェックします。存在する最後のリソースが選択されて使用されます。私のアプリをjava -jar myapp.jar --properties.location = / directory / myproperties.propertiesで起動して、ボートを浮かぶプロパティの場所を使用できます。

ここで重要な詳細:プロパティが設定されていない場合のエラーを回避するには、@ Valueアノテーションのproperties.locationのデフォルト値として空の文字列を使用します。

properties.locationの規則は、次のとおりです。properties.locationとして、ディレクトリーまたはプロパティー・ファイルへのパスを使用します。

特定のプロパティのみをオーバーライドする場合は、setIgnoreResourceNotFound(true)を指定したPropertiesFactoryBeanを、場所として設定されたリソース配列とともに使用できます。

このソリューションは、複数のファイルを処理するように拡張できると確信しています...

編集

ここで、複数のファイルに対する私の解決策:)前と同様に、これはPropertiesFactoryBeanと組み合わせることができます。

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;
    }

}

素晴らしい回避策。そのようなjava8構成体!とにかく、1つだけではなく複数のプロパティBeanが必要なので、それを使用することはできません。私のEDITSが表示された場合、私の回避策はかなり似ており、私のユースケースにきちんと対応しています。
2015年

私は完全を
期す

6

スプリングブートを使用すると、異なる環境用に異なるプロファイルを書き込むことができます。たとえば、本番環境、QA、ローカル環境用に個別のプロパティファイルを作成できます。

ローカルマシンに応じた設定を含むapplication-local.propertiesファイルは

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

同様に、application-prod.propertiesおよびapplication-qa.propertiesを必要な数だけプロパティファイルに書き込むことができます。

次に、いくつかのスクリプトを記述して、さまざまな環境でアプリケーションを起動します。

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

5

私はこれと同様の問題を抱えていて、最終的に原因を突き止めました:application.propertiesファイルの所有権とrwx属性が間違っていました。したがって、tomcatを起動したとき、application.propertiesファイルは正しい場所にありましたが、別のユーザーが所有していました。

$ chmod 766 application.properties

$ chown tomcat application.properties

同様の問題があると思います。Tomcatをoptフォルダにインストールしました。アプリケーションファイルはどこに配置しましたか?フォルダ属性も変更する必要がありますか?
anakin59490

3

@mxsbソリューションの変更されたバージョンで、複数のファイルを定義できます。私の場合、これらはymlファイルです。

私のapplication-dev.ymlに、-dev.ymlが含まれるすべてのymlを注入できるようにするこの構成を追加しました。これは特定のファイルのリストでもかまいません。「classpath:/test/test.yml、classpath:/test2/test.yml」

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

これは、プロパティマップを取得するのに役立ちます。

@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);
    }
}
}

しかし、私の場合のように、プロファイルごとにymlファイルを分割してロードし、Beanの初期化の前にそれをSpring構成に直接注入する必要がありました。

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

...あなたはアイデアを得ます

コンポーネントは少し異なります

@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);
    }
}

}


3

application.propertiesファイルで指定された値をオーバーライドする場合は、アプリケーションの実行中にアクティブなプロファイルを変更し、プロファイルのアプリケーションプロパティファイルを作成できます。たとえば、アクティブなプロファイル "override"を指定して、/ tmpの下に "application-override.properties"という新しいアプリケーションプロパティファイルを作成したと仮定すると、次のように実行できます。

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

spring.config.locationで指定された値は、逆の順序で評価されます。したがって、私の例では、最初にclasspatが評価され、次にファイル値が評価されます。

jarファイルと「application-override.properties」ファイルが現在のディレクトリにある場合、実際には単純に使用できます。

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

Spring Bootがプロパティファイルを見つけるので


1
これは、「override」プロファイルをアクティブプロファイルとして使用するようにSpringに指示します。実際、application.ymlファイルまたはapplication.propertiesファイルで指定された値を
上書きし

私の場合は、設定ファイル.ymalまたは.propertiesのフォルダー内を検索します。私はapplication-profile.ymlのみを配置してから、正しく取得します。ありがとう@acaruciいい旅でした
Ahmed Salem

0

私はこれが従うべき有用なパターンであることを発見しました:

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

ここでは、「application-MyTest_LowerImportance.yml」と「application-MyTest_MostImportant.yml」を使用するように「application.yml」の使用をオーバーライドします
(Springは.propertiesファイルも検索します)。

また、追加のボーナスとして、デバッグとトレースの設定が別の行に含まれているので、必要に応じてコメント化できます;]

Springはロードするすべてのファイルとロードしようとするファイルの名前をダンプするため、デバッグ/トレースは非常に便利です。
実行時にコンソールに次のような行が表示されます。

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

-1

これを理解しようとすると、多くの問題に遭遇しました。これが私のセットアップです

開発環境:Windows 10、Java:1.8.0_25、Spring Boot:2.0.3.RELEASE、Spring:5.0.7.RELEASE

私が見つけたのは、春が「構成の適切なデフォルト」という概念に固執していることです。これは、すべてのプロパティファイルをwarファイルの一部として持っている必要があります。そこに移動したら、「-spring.config.additional-location」コマンドラインプロパティを使用してそれらをオーバーライドし、外部プロパティファイルを指定できます。ただし、プロパティファイルが元のwarファイルの一部でない場合は機能しません。

デモコード:https : //github.com/gselvara/spring-boot-property-demo/tree/master

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.