私はこれに対する解決策を見つけることができました。このソリューションの目的は次のとおりです。
- 共有ライブラリのyamlファイルから値をロードします。
- ライブラリを使用しているアプリケーションが、環境にも読み込まれる独自のbootstrap.ymlを導入できるようにします。
- bootstrap.ymlの値は共有yamlの値を上書きする必要があります。
主な課題は、アプリケーションライフサイクルの適切な時点でコードを注入することです。具体的には、bootstrap.yml PropertySourceが環境に追加された後(カスタムPropertySourceを相対的に正しい順序で注入できるように)、アプリケーションがBeanの設定を開始する前に行う必要があります(設定値の制御動作)。
私が見つけた解決策は、カスタムEnvironmentPostProcessor
public class CloudyConfigEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
private YamlPropertySourceLoader loader;
public CloudyConfigEnvironmentPostProcessor() {
loader = new YamlPropertySourceLoader();
}
@Override
public void postProcessEnvironment(ConfigurableEnvironment env, SpringApplication application) {
//ensure that the bootstrap file is only loaded in the bootstrap context
if (env.getPropertySources().contains("bootstrap")) {
//Each document in the multi-document yaml must be loaded separately.
//Start by loading the no-profile configs...
loadProfile("cloudy-bootstrap", env, null);
//Then loop through the active profiles and load them.
for (String profile: env.getActiveProfiles()) {
loadProfile("cloudy-bootstrap", env, profile);
}
}
}
private void loadProfile(String prefix, ConfigurableEnvironment env, String profile) {
try {
PropertySource<?> propertySource = loader.load(prefix + (profile != null ? "-" + profile: ""), new ClassPathResource(prefix + ".yml"), profile);
//propertySource will be null if the profile isn't represented in the yml, so skip it if this is the case.
if (propertySource != null) {
//add PropertySource after the "applicationConfigurationProperties" source to allow the default yml to override these.
env.getPropertySources().addAfter("applicationConfigurationProperties", propertySource);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public int getOrder() {
//must go after ConfigFileApplicationListener
return Ordered.HIGHEST_PRECEDENCE + 11;
}
}
を使用していたこのカスタムEnvironmentPostProcessorは、META-INF/spring.factoriesを介して注入することができます。
#Environment PostProcessors
org.springframework.boot.env.EnvironmentPostProcessor=\
com.mycompany.cloudy.bootstrap.autoconfig.CloudyConfigEnvironmentPostProcessor
カップルの事に注意する:
- YamlPropertySourceLoaderはyamlプロパティをプロファイルで読み込むため、 document yamlファイルを作成する必要があります。これは、プロファイルなしの設定を含め、実際に別のプロファイルを個別にロードする必要があります。
- ConfigFileApplicationListenerは、環境にbootstrap.yml(または通常のコンテキストではapplication.yml)を読み込むEnvironmentPostProcessorです。したがって、bootstrap.ymlプロパティに優先してカスタムyamlプロパティを優先的に配置するには、 ConfigFileApplicationListenerの後にカスタムのEnvironmentPostProcessorを注文します。
編集:初期の回答が機能しませんでした。私はこれをこのものに置き換えています。
私はあなたがbootstrap.yml自身でそれを行うことができないと思いますが、あなたは、ブートストラップ・メカニズムに差し込むことができプロパティーソースにデフォルト値を設定します。 – spencergibb
なぜyamlファイルですか? Java構成を作成することができます。それは配布がより簡単になります。 –
確かにjavaは配布しやすくなります。しかし、私はyamlで非常に簡単にできることを達成するために、大量のカスタマイズを行う必要があります。たとえば、特定のプロファイルの下で春のクラウドバスをオフにするjavaconfigを提供するだけでは、コンベンション上の設定に関してかなり難しいですが、単純なspring.cloud.bus.enabled = falseでyamlで行うことができます。デフォルトのユーレカdefaultZoneを提供するために、私は自分自身でBeanを構成することを考えています。 – shazbot