簡體   English   中英

如何構建自定義PropertySource以綁定到@ConfigurationProperties

[英]How to build custom PropertySource for binding to @ConfigurationProperties

我們正在創建一個新的PropertySource ,它使用數據庫作為它的存儲庫。 我們的想法是我們可以在運行時更新屬性值。

同時,我們希望使用@ConfigurationProperties ,以便我們可以包含驗證以及使用application- {profile}命名約定。

但是,看起來@ConfigurationProperties值只從“applicationConfig:[path / to / config]” PropertySource加載。 例如,以下測試:

private final String OVERRIDEN_VALUE = "overriden value";

@Before
public void before() {

    LOGGER.debug("Property sources are: "); 
    for(Iterator<?> it = env.getPropertySources().iterator(); it.hasNext(); ) {
        PropertySource<?> propertySource = (PropertySource<?>) it.next();
        LOGGER.debug(propertySource.getName());
    }

    EnvironmentTestUtils.addEnvironment("integrationTest", env, "some.prefix.overridable-property=" + OVERRIDEN_VALUE);

}

@Test
public void testOverridingDefaultProperties() {

    LOGGER.debug("MutablePropertySources value: {}", env.getProperty("some.prefix.overridable-property"));
    LOGGER.debug("@ConfigurationProperties value: {}", testProperties.getOverridableProperty());

    Assert.assertEquals(OVERRIDEN_VALUE, testProperties.getOverridableProperty());

}

生成此輸出:

Property sources are: 
    systemProperties
    systemEnvironment
    random
    integrationTest
    applicationConfig: [classpath:/path/to/my/application.yml]

MutablePropertySources value: overriden value
@ConfigurationProperties value: default value

更多情況下,我原來問的春天啟動的Github上這個問題在這里

感謝Spring Boot的人們。 向我指出Spring Cloud Context

http://projects.spring.io/spring-cloud/spring-cloud.html#customizing-bootstrap-property-sources

看起來這樣可以解決問題。

更新:

由於我們已經編寫了額外的數據庫支持的PropertySource ,因此我們只需要在運行時刷新@ConfigurationProperties 同時我們不想刷新所有@ConfigurationProperties 為了完成刷新,我們做了以下事情:

  1. 創建了一個名為@ReloadableProperties的注釋
  2. 創建了以下實用程序bean,它使用Spring Boot的ConfigurationPropertiesBindingPostProcessor
/**
 * 
 * Helper bean to reload {@code @ConfigurationProperties}
 * if the {@code @ConfigurationProperties} bean is annotated 
 * with {@code @ReloadableProperties}.
 * 
 * @author Jonathan Martin
 * @since 2.0.0
 * 
 * @see ReloadableProperties
 * @see ConfigurationPropertiesBindingPostProcessor
 *
 */
public class ConfigurationPropertiesReloader {

    private final ApplicationContext context;

    private final ConfigurationPropertiesBindingPostProcessor processor;

    @Autowired
    public ConfigurationPropertiesReloader(ApplicationContext context,  ConfigurationPropertiesBindingPostProcessor processor) {
        this.context = context;
        this.processor = processor;
    }

    /**
     * Reload all {@code @ConfigurationProperties}
     * annotated with {@code @ReloadableProperties}.
     */
    public void reload() {
        Map beans = context.getBeansWithAnnotation(ReloadableProperties.class);
        for (Map.Entry entry : beans.entrySet()) {

            String beanName = entry.getKey();
            Object bean = entry.getValue();

            ConfigurationProperties annotation = AnnotationUtils.findAnnotation(bean.getClass(), ConfigurationProperties.class);

            // Only reload the bean if it's an @ConfigurationProperties
            // Can't check for instance of ConfigurationPropertiesHolder 
            // because it uses package scope.
            if (annotation != null) {
                processor.postProcessBeforeInitialization(bean, beanName);
            }

        }
    }

}

現在,如果我將實用程序bean注入我的測試並調用重新加載,則測試通過。

暫無
暫無

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

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