gpt4 book ai didi

java - 如何构建自定义 PropertySource 以绑定(bind)到 @ConfigurationProperties

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:18:45 26 4
gpt4 key购买 nike

我们正在创建一个使用数据库作为存储库的新 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

有关更多上下文,我最初在 Spring Boot 的 Github 上问过这个问题 here .

最佳答案

感谢 Spring Boot 人员。向我指出 Spring Cloud Context

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

看起来这样就可以了。

更新:

因为我们已经编写了额外的数据库支持的PropertySource,所以我们实际上只需要在运行时刷新@ConfigurationProperties。同时我们不想刷新所有的@ConfigurationProperties。为完成刷新,我们执行了以下操作:

  1. 创建了一个名为 @ReloadableProperties 的注释
  2. 创建了以下使用 Spring Boot 的 ConfigurationPropertiesBindingPostProcessor
  3. 的实用程序 bean
/** *  * 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 注入(inject)到我的测试中并调用重新加载,测试就会通过。

关于java - 如何构建自定义 PropertySource 以绑定(bind)到 @ConfigurationProperties,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31456216/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com