[英]how to manage spring-cloud bootstrap properties in a shared library?
我正在構建一個庫,它為使用我們的Spring Cloud Config/Eureka
設置的應用程序提供了一個固定的配置。 我們的想法是將此配置作為自定義啟動器提供,在單個微服務應用程序中很少或不使用與Spring相關的樣板。
此時,我想要放在此庫中的大多數共享配置都包含在bootstrap.yml
。 我想在我的自定義啟動器中提供bootstrap.yml
,但使用該庫的應用程序仍然需要能夠提供自己的bootstrap.yml
,即使這樣他們也可以正確設置spring.application.name。
由於從類路徑加載bootstrap.yml
的方式,如果應用程序有自己的bootstrap.yml
,Spring似乎忽略了共享庫中的那個。 我甚至無法使用ApplicationContextInitializer
來自定義環境,因為引導上下文處理ApplicationContextInitializers
的特殊方式。
有沒有人對這里可行的方法有任何建議? 我想提供一個drop-in lib,它使我們自以為是的bootstrap配置工作,而不必在所有項目中復制樣板bootstrap.yml
。
您可以使用META-INF/spring.factories
文件中的org.springframework.cloud.bootstrap.BootstrapConfiguration
鍵將共享庫中的PropertySource添加到引導屬性中。
例如,您可以創建包含以下內容的庫:
的src /主/ JAVA / COM /示例/ MYLIB / MyLibConfig.java
package com.example.mylib;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@PropertySource("classpath:mylib-config.properties")
public class MyLibConfig {
}
SRC /主/資源/ mylib-config.properties
eureka.instance.public=true
# or whatever...
SRC /主/資源/ META-INF / spring.factories
org.springframework.cloud.bootstrap.BootstrapConfiguration=com.example.mylib.MyLibConfig
更多細節: http : //projects.spring.io/spring-cloud/spring-cloud.html#_customizing_the_bootstrap_configuration
我能夠找到解決方案。 該解決方案的目標是:
主要挑戰是在應用程序生命周期的適當位置注入一些代碼。 具體來說,我們需要在將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;
}
}
可以通過META-INF / spring.factories注入此自定義EnvironmentPostProcessor:
#Environment PostProcessors
org.springframework.boot.env.EnvironmentPostProcessor=\
com.mycompany.cloudy.bootstrap.autoconfig.CloudyConfigEnvironmentPostProcessor
有幾點需要注意:
編輯:我的初步答案不起作用。 我正在用這個取而代之。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.