SpringおよびSpring Bootのプロパティ
1. 概要
このチュートリアルでは、Properties in Springをセットアップして使用する方法を示します– Java構成と@PropertySourceを介して、またはXMLと<property-placeholder>,as well how properties work in Spring Boot.を介して
参考文献:
春の表現言語ガイド
この記事では、実行時にオブジェクトグラフのクエリと操作をサポートする強力な式言語であるSpring Expression Language(SpEL)について説明します。
Spring Bootの@ConfigurationPropertiesのガイド
Spring Bootの@ConfigurationPropertiesアノテーションの迅速で実用的なガイド。
2. Javaアノテーションを介してプロパティファイルを登録する
Spring 3.1では、プロパティソースを環境に追加するための便利なメカニズムとして、the new @PropertySource annotationも導入されています。 このアノテーションは、Javaベースの構成および@Configurationアノテーションと組み合わせて使用されます。
@Configuration
@PropertySource("classpath:foo.properties")
public class PropertiesWithJavaConfig {
//...
}
新しいプロパティファイルを登録するもう1つの非常に便利な方法は、プレースホルダーを使用してdynamically select the right file at runtimeを実行できるようにすることです。例えば:
@PropertySource({
"classpath:persistence-${envTarget:mysql}.properties"
})
...
2.1. 複数のプロパティの場所の定義
@PropertySourceアノテーションは繰り返し可能なaccording to Java 8 conventionsです。 したがって、Java 8以降を使用している場合は、このアノテーションを使用して複数のプロパティの場所を定義できます。
@PropertySource("classpath:foo.properties")
@PropertySource("classpath:bar.properties")
public class PropertiesWithJavaConfig {
//...
}
もちろん、@PropertySourcesアノテーションを使用して、@PropertySourceの配列を指定することもできます。 これは、Java 8以降だけでなく、サポートされているすべてのJavaバージョンで機能します。
@PropertySources({
@PropertySource("classpath:foo.properties"),
@PropertySource("classpath:bar.properties")
})
public class PropertiesWithJavaConfig {
//...
}
いずれの場合も、in the event of a property name collision, the last source read takes precedenceであることに注意してください。
3. プロパティファイルをXMLで登録する
XMLでは、新しいプロパティファイルをthe <context:property-placeholder … > namespace elementを介してSpringにアクセスできるようにすることができます。
foo.propertiesファイルは、実行時にクラスパスで使用できるように、/src/main/resourcesの下に配置する必要があります。
Springコンテキストにmultiple <property-placeholder> elementsが存在する場合、いくつかの推奨されるベストプラクティスがあります。
-
これらがSpringによって処理される順序を修正するには、order属性を指定する必要があります。
-
すべてのプロパティプレースホルダーから最後のプレースホルダー(最高のorder)を引いたものには、例外をスローせずに解決メカニズムをコンテキスト内の他のユーザーに渡すことができるように、ignore-unresolvable=”true”が必要です。
3.1. 複数のプロパティファイルをXMLで登録する
前のセクションでは、Java 8以降のアノテーションを使用して複数のプロパティファイルを定義する方法を説明しました。 同様に、define multiple properties files using XML configuration:
そして、前と同じように、in the event of a property name collision, the last source read takes precedence。
4. プロパティの使用/挿入
Injecting a property with the @Value annotationは簡単です:
@Value( "${jdbc.url}" )
private String jdbcUrl;
A default value of the propertyも指定できます。
@Value( "${jdbc.url:aDefaultUrl}" )
private String jdbcUrl;
Spring XML設定でプロパティを使用する:
Spring 3.1で追加された古いPropertyPlaceholderConfigurerと新しいPropertySourcesPlaceholderConfigurerの両方が、Bean定義プロパティ値と@Valueアノテーション内にresolve $\{…} placeholdersします。
最後に–できます obtain the value of a property using the Environment API:
@Autowired
private Environment env;
...
dataSource.setUrl(env.getProperty("jdbc.url"));
ここでの非常に重要な注意点は、using <property-placeholder> will not expose the properties to the Spring Environmentです。これは、このような値の取得が機能しないことを意味します。nullが返されます。
env.getProperty("key.something")
5. SpringBootのプロパティ
プロパティのより高度な構成オプションに入る前に、the new properties support in Spring Bootを見てみましょう。
一般的に、この新しいサポートには、標準のSpringと比較してless configurationが含まれます。これは、もちろん、Bootの主な目標の1つです。
5.1. application.properties –デフォルトのプロパティファイル
ブートは、構成アプローチよりも一般的な規則をプロパティファイルに適用します。 これは、「src/main/resources」ディレクトリに「application.properties」ファイルを置くだけで、自動検出されることを意味します。 その後、ロードされたプロパティを通常どおり注入できます。
したがって、このデフォルトファイルを使用することで、PropertySourceを明示的に登録したり、プロパティファイルへのパスを指定したりする必要はありません。
環境プロパティを使用して、必要に応じて実行時に別のファイルを構成することもできます。
java -jar app.jar --spring.config.location=classpath:/another-location.properties
5.2. 環境固有のプロパティファイル
さまざまな環境をターゲットにする必要がある場合は、Bootにそのための組み込みメカニズムがあります。
“src/main/resources”ディレクトリに“application-environment.properties”ファイルを定義するだけで、同じ環境名でSpringプロファイルを設定できます。
たとえば、「ステージング」環境を定義する場合、stagingプロファイルを定義してから、application-staging.propertiesを定義する必要があることを意味します。
このenvファイルがロードされ、will take precedence over the default property fileがロードされます。 デフォルトのファイルは引き続き読み込まれることに注意してください。プロパティの衝突が発生した場合は、環境固有のプロパティファイルが優先されます。
5.3. 特定のプロパティファイルをテストする
また、アプリケーションのテスト中に異なるプロパティ値を使用する必要がある場合があります。
Spring Bootは、テスト実行中に「src/test/resources」ディレクトリを調べることでこれを処理します。 繰り返しますが、デフォルトのプロパティは通常どおり注入可能ですが、衝突が発生するとこれらのプロパティはオーバーライドされます。
5.4. @TestPropertySource注釈
テストプロパティをより細かく制御する必要がある場合は、@TestPropertySourceアノテーションを利用できます。
これにより、デフォルトのプロパティソースよりも優先して、特定のテストコンテキストのテストプロパティを設定できます。
@ContextConfiguration
@TestPropertySource("/my-test.properties")
public class IntegrationTests {
// tests
}
ファイルを使用したくない場合は、名前と値を直接指定できます。
@ContextConfiguration
@TestPropertySource("foo=bar", "bar=foo")
public class IntegrationTests {
// tests
}
@SpringBootTestアノテーションのproperties引数を使用して、同様の効果を実現することもできます。
@SpringBootTest(properties = {"foo=bar", "bar=foo"})
public class IntegrationTests {
// tests
}
5.5. 階層プロパティ
グループ化されたプロパティがある場合は、@ConfigurationPropertiesアノテーションを使用して、これらのプロパティ階層をJavaオブジェクトグラフにマップできます。
データベース接続の構成に使用されるいくつかのプロパティを見てみましょう。
database.url=jdbc:postgresql:/localhost:5432/instance
database.username=foo
database.password=bar
次に、注釈を使用してそれらをデータベースオブジェクトにマップしましょう。
@ConfigurationProperties(prefix = "database")
public class Database {
String url;
String username;
String password;
// standard getters and setters
}
Spring Bootは、設定より規約を再度適用し、プロパティ名とそれに対応するフィールドを自動的にマッピングします。 指定する必要があるのは、プロパティプレフィックスのみです。
構成プロパティをさらに深く掘り下げたい場合は、the in-depth articleを参照してください。
5.6. 代替–YAMLファイル
YAMLファイルもサポートされています。
テスト固有、環境固有、およびデフォルトのプロパティファイルには、すべて同じ命名規則が適用されます。 唯一の違いは、ファイル拡張子と、クラスパス上にあるSnakeYAMLライブラリへの依存性です。
YAMLは、階層的なプロパティストレージに特に適しています。次のプロパティファイル:
database.url=jdbc:postgresql:/localhost:5432/instance
database.username=foo
database.password=bar
secret: foo
次のYAMLファイルと同義です。
database:
url: jdbc:postgresql:/localhost:5432/instance
username: foo
password: bar
secret: foo
YAMLファイルは@PropertySourceアノテーションをサポートしていないため、アノテーションの使用が必要な場合は、プロパティファイルの使用に制限されることにも言及する価値があります。
5.7. コマンドライン引数からのプロパティ
ファイルを使用するのではなく、プロパティをコマンドラインで直接渡すことができます。
java -jar app.jar --property="value"
これは、-jarコマンドの後ではなく前に提供されるシステムプロパティを介して行うこともできます。
java -Dproperty.name="value" -jar app.jar
5.8. 環境変数のプロパティ
Spring Bootは環境変数も検出し、それらをプロパティとして扱います。
export name=value
java -jar app.jar
5.9 Randomization of Property Values
決定論的なプロパティ値が必要ない場合は、RandomValuePropertySourceを使用してプロパティの値をランダム化できます。
random.number=${random.int}
random.long=${random.long}
random.uuid=${random.uuid}
5.10. 追加のタイプのプロパティソース
Spring Bootは多数のプロパティソースをサポートし、賢明なオーバーライドを可能にするためによく考えられた順序を実装しています。 この記事の範囲を超えたofficial documentationを参照する価値があります。
6. Spring 3.0でのRawBeansを使用した構成–PropertyPlaceholderConfigurer
プロパティをSpringに取り込む便利な方法(アノテーションとXML名前空間)に加えて、プロパティ構成Beanもmanuallyで定義および登録できます。 PropertyPlaceholderConfigurerを使用すると、構成を完全に制御できますが、より冗長で、ほとんどの場合、不要であるという欠点があります。
6.1. 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. XML設定
classpath:foo.properties
7. Spring 3.1でのRawBeansを使用した構成–PropertySourcesPlaceholderConfigurer
同様に、Spring 3.1では、新しいPropertySourcesPlaceholderConfigurerを手動で構成することもできます。
7.1. 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. XML設定
classpath:foo.properties
8. 親子コンテキストのプロパティ
この質問は何度も何度も出てきます-あなたのweb application has a parent and a child contextはどうなりますか? 親コンテキストには、いくつかの共通のコア機能とBeanがあり、次にサーブレット固有のBeanを含む1つ(または複数)の子コンテキストがあります。
その場合、プロパティファイルを定義してこれらのコンテキストに含める最良の方法は何ですか? さらに、これらのプロパティをSpringから最適に取得する方法は? 以下に簡単な内訳を示します。
8.1. プロパティファイルがroperty-placeholder>のXMLで定義されている場合
ファイルがdefined in the Parent contextの場合:
-
@ValueはChild contextで機能します:いいえ
-
@ValueはParent contextで機能します:はい
ファイルがdefined in the Child contextの場合:
-
@ValueはChild contextで機能します:はい
-
@ValueはParent contextで機能します:いいえ
最後に、前に説明したように、<property-placeholder>はプロパティを環境に公開しないため、次のようになります。
-
environment.getPropertyはeither contextで機能します:いいえ
8.2. プロパティファイルが@PropertySourceを使用してJavaで定義されている場合
ファイルがdefined in the Parent contextの場合:
-
@ValueはChild contextで機能します:はい
-
@ValueはParent contextで機能します:はい
-
Child contextのenvironment.getProperty:はい
-
Parent contextのenvironment.getProperty:はい
ファイルがdefined in the Child contextの場合:
-
@ValueはChild contextで機能します:はい
-
@ValueはParent contextで機能します:いいえ
-
Child contextのenvironment.getProperty:はい
-
Parent contextのenvironment.getProperty:いいえ
9. 結論
この記事では、いくつかのexamples of working with properties and properties files in Springを示しています。
いつものように、記事を裏付けるコード全体がover on Githubで利用可能です。 これはMavenベースのプロジェクトであるため、インポートしてそのまま実行するのは簡単です。