簡體   English   中英

如何在共享庫中管理spring-cloud bootstrap屬性?

[英]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

我能夠找到解決方案。 該解決方案的目標是:

  • 將yaml文件中的值加載到共享庫中。
  • 允許使用該庫的應用程序引入自己的bootstrap.yml,它也會加載到Environment中。
  • 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;
    }

}

可以通過META-INF / spring.factories注入此自定義EnvironmentPostProcessor:

#Environment PostProcessors
org.springframework.boot.env.EnvironmentPostProcessor=\
com.mycompany.cloudy.bootstrap.autoconfig.CloudyConfigEnvironmentPostProcessor

有幾點需要注意:

  • YamlPropertySourceLoader按配置文件加載yaml屬性,因此如果您使用的是多文檔yaml文件,則需要單獨從中加載每個配置文件,包括無配置文件配置。
  • ConfigFileApplicationListener是EnvironmentPostProcessor,負責將bootstrap.yml(或常規上下文的application.yml)加載到Environment中,因此為了相對於bootstrap.yml屬性正確定位自定義yaml屬性,您需要訂購ConfigFileApplicationListener之后的自定義EnvironmentPostProcessor。

編輯:我的初步答案不起作用。 我正在用這個取而代之。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM