我正在构建一个库,该库为使用我们的Spring Cloud Config/Eureka设置的应用程序提供了合理的配置。这个想法是作为单个微服务应用程序中很少或没有与Spring云相关的样板的定制启动程序提供此配置的。
Spring Cloud Config/Eureka
此时,我要放入此库中的大多数共享配置都包含中的内容bootstrap.yml。我想bootstrap.yml在我的自定义启动器中提供,但是使用该库的应用程序仍然需要能够提供自己的bootstrap.yml,即使这样也可以正确设置spring.application.name。
bootstrap.yml
由于bootstrap.yml是从类路径加载的,因此,如果应用程序具有自己的,Spring似乎会忽略共享库中的那个bootstrap.yml。ApplicationContextInitializer由于引导上下文对待的特殊方式,我什至无法使用自定义环境ApplicationContextInitializers。
ApplicationContextInitializer
ApplicationContextInitializers
有人对在这里可行的方法有任何建议吗?我想提供一个嵌入式库,使我们自以为是的引导程序配置工作,而不必bootstrap.yml在所有项目中都复制样板。
我能够找到解决方案。该解决方案的目标是:
主要挑战是在应用程序生命周期的适当时间点注入一些代码。具体来说,我们需要在将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
需要注意的几件事:
编辑:我最初的答案不起作用。 我要用这个代替它。