Spring Boot 以下のapplication.yml
のアプリケーションがあります-基本的に here から取得:
info:
build:
artifact: ${project.artifactId}
name: ${project.name}
description: ${project.description}
version: ${project.version}
特定の値を注入できます。
@Value("${info.build.artifact}") String value
ただし、マップ全体、つまり次のようなものを挿入したいと思います。
@Value("${info}") Map<String, Object> info
それ(または同様のもの)は可能ですか?もちろん、yamlを直接読み込むことはできますが、Springで既にサポートされているものがあるのではないかと思っていました。
@ConfigurationProperties
を使用してマップを挿入できます。
import Java.util.HashMap;
import Java.util.Map;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableAutoConfiguration
@EnableConfigurationProperties
public class MapBindingSample {
public static void main(String[] args) throws Exception {
System.out.println(SpringApplication.run(MapBindingSample.class, args)
.getBean(Test.class).getInfo());
}
@Bean
@ConfigurationProperties
public Test test() {
return new Test();
}
public static class Test {
private Map<String, Object> info = new HashMap<String, Object>();
public Map<String, Object> getInfo() {
return this.info;
}
}
}
質問のyamlでこれを実行すると、以下が生成されます。
{build={artifact=${project.artifactId}, version=${project.version}, name=${project.name}, description=${project.description}}}
プレフィックスの設定、欠落しているプロパティの処理方法の制御など、さまざまなオプションがあります。詳細については、 javadoc を参照してください。
以下のソリューションは、@ Andy Wilkinsonのソリューションの短縮形です。ただし、個別のクラスまたは@Bean
アノテーション付きメソッドを使用する必要はありません。
application.yml:
input:
name: raja
age: 12
somedata:
abcd: 1
bcbd: 2
cdbd: 3
SomeComponent.Java:
@Component
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "input")
class SomeComponent {
@Value("${input.name}")
private String name;
@Value("${input.age}")
private Integer age;
private HashMap<String, Integer> somedata;
public HashMap<String, Integer> getSomedata() {
return somedata;
}
public void setSomedata(HashMap<String, Integer> somedata) {
this.somedata = somedata;
}
}
@Value
アノテーションと@ConfigurationProperties
の両方をクラブできます。問題はありません。ただし、ゲッターとセッターは重要であり、@EnableConfigurationProperties
が機能するには@ConfigurationProperties
が必要です。
@Szymon Stepniakが提供するグルーヴィーなソリューションからこのアイデアを試しました。誰かに役立つと思いました。
今日同じ問題に遭遇しましたが、残念ながらアンディのソリューションはうまくいきませんでした。 Spring Boot 1.2.1.RELEASEではさらに簡単ですが、いくつかの点に注意する必要があります。
application.yml
の興味深い部分は次のとおりです。
oauth:
providers:
google:
api: org.scribe.builder.api.Google2Api
key: api_key
secret: api_secret
callback: http://callback.your.Host/oauth/google
providers
マップにはマップエントリが1つしか含まれていません。私の目標は、他のOAuthプロバイダーに動的構成を提供することです。このマップを、このyamlファイルで提供された設定に基づいてサービスを初期化するサービスに挿入します。私の最初の実装は:
@Service
@ConfigurationProperties(prefix = 'oauth')
class OAuth2ProvidersService implements InitializingBean {
private Map<String, Map<String, String>> providers = [:]
@Override
void afterPropertiesSet() throws Exception {
initialize()
}
private void initialize() {
//....
}
}
アプリケーションの起動後、OAuth2ProvidersService
のproviders
マップが初期化されませんでした。 Andyが提案した解決策を試しましたが、うまくいきませんでした。そのアプリケーションではGroovyを使用しているので、private
を削除し、Groovyにゲッターとセッターを生成させることにしました。したがって、私のコードは次のようになりました。
@Service
@ConfigurationProperties(prefix = 'oauth')
class OAuth2ProvidersService implements InitializingBean {
Map<String, Map<String, String>> providers = [:]
@Override
void afterPropertiesSet() throws Exception {
initialize()
}
private void initialize() {
//....
}
}
その小さな変更の後、すべてが機能しました。
言及する価値があるかもしれないものが1つありますが。動作させた後、このフィールドをprivate
にして、setterメソッドでセッターにストレート引数タイプを提供することにしました。残念ながらそれは機能しません。次のメッセージでorg.springframework.beans.NotWritablePropertyException
が発生します。
Invalid property 'providers[google]' of bean class [com.zinvoice.user.service.OAuth2ProvidersService]: Cannot access indexed value in property referenced in indexed property path 'providers[google]'; nested exception is org.springframework.beans.NotReadablePropertyException: Invalid property 'providers[google]' of bean class [com.zinvoice.user.service.OAuth2ProvidersService]: Bean property 'providers[google]' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
Spring BootアプリケーションでGroovyを使用している場合は、注意してください。
構成からマップを取得するには、構成クラスが必要です。残念ながら、@ Valueアノテーションではうまくいきません。
Application.yml
entries:
map:
key1: value1
key2: value2
構成クラス:
@Component
@ConfigurationProperties("entries")
@Getter
@Setter
public static class MyConfig {
private Map<String, String> map;
}
foo.bars.one.counter=1
foo.bars.one.active=false
foo.bars[two].id=IdOfBarWithKeyTwo
public class Foo {
private Map<String, Bar> bars = new HashMap<>();
public Map<String, Bar> getBars() { .... }
}
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-Configuration-Binding