sha*_*bot 5 spring spring-boot spring-cloud netflix-eureka
我正在构建一个库,它为使用我们Spring Cloud Config/Eureka设置的应用程序提供了一个固定的配置.我们的想法是将此配置作为自定义启动器提供,在单个微服务应用程序中很少或不使用与Spring相关的样板.
此时,我想要放入此库中的大部分共享配置都包含在内容中bootstrap.yml.我想bootstrap.yml在我的自定义启动器中提供,但使用该库的应用程序仍然需要能够提供它们自己的bootstrap.yml,即使只是这样他们可以正确设置他们的spring.application.name.
由于bootstrap.yml从类路径加载的方式,如果应用程序有自己的方式,Spring似乎忽略了共享库中的那个bootstrap.yml.ApplicationContextInitializer由于引导上下文处理的特殊方式,我甚至无法使用自定义环境ApplicationContextInitializers.
有没有人对这里可行的方法有任何建议?我想提供一个drop-in lib,使我们自以为是的bootstrap配置工作,而不必bootstrap.yml在所有项目中复制样板.
您可以使用文件中的org.springframework.cloud.bootstrap.BootstrapConfiguration密钥将共享库中的 PropertySource 添加到引导程序属性META-INF/spring.factories。
例如,您可以创建一个包含以下内容的库:
src/main/java/com/example/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 {
}
Run Code Online (Sandbox Code Playgroud)
src/main/resources/mylib-config.properties
eureka.instance.public=true
# or whatever...
Run Code Online (Sandbox Code Playgroud)
src/main/resources/META-INF/spring.factories
org.springframework.cloud.bootstrap.BootstrapConfiguration=com.example.mylib.MyLibConfig
Run Code Online (Sandbox Code Playgroud)
更多详情:http : //projects.spring.io/spring-cloud/spring-cloud.html#_customizing_the_bootstrap_configuration
我能够找到解决方案。该解决方案的目标是:
主要挑战是在应用程序生命周期的适当时刻注入一些代码。具体来说,我们需要在 bootstrap.yml PropertySource 添加到环境之后(以便我们可以按照相对于它的正确顺序注入自定义 PropertySource),但也要在应用程序开始配置 beans 之前执行此操作(因为我们的配置值控制行为)。
我找到的解决方案是使用自定义的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;
}
}
Run Code Online (Sandbox Code Playgroud)
这个自定义的EnvironmentPostProcessor可以通过META-INF/spring.factories注入:
#Environment PostProcessors
org.springframework.boot.env.EnvironmentPostProcessor=\
com.mycompany.cloudy.bootstrap.autoconfig.CloudyConfigEnvironmentPostProcessor
Run Code Online (Sandbox Code Playgroud)
有几点需要注意:
编辑:我最初的答案不起作用。我把它换成这个,确实如此。
| 归档时间: |
|
| 查看次数: |
2587 次 |
| 最近记录: |