一尘不染

Java Spring Boot:无需Spring Cloud配置服务器即可重新加载配置

spring-boot

我正在尝试在运行时重新加载应用程序的配置。该配置位于yaml文件中,并且@ConfigurationProperties按预期进行绑定。接下来是。yaml更改后,我想重新加载配置。或更确切地说,我正在检查@Scheduled文件是否已更改。

我想避免运行第二台服务器进行Environment更新。我有两个问题:

  1. ConfigurableEnvironment也许如何更新环境?
  2. 我该如何传播这些?

Spring Cloud配置文档说明:

EnvironmentChangeEvent只要您可以实际更改Environment和发布事件(这些API是公共的并且是Spring核心的一部分),本章就涵盖了一大类刷新用例。

因此,发布事件是可行的,但是我不了解如何实际更新属性。


阅读 404

收藏
2020-05-30

共1个答案

一尘不染

关于这一点,有很多讨论:如何在没有任何配置服务器的情况下刷新属性。此处有Dave
Syer帖子,它带来了一些启发-但仍然不言自明。

接下来是spring-boot / -cloud的最自然的方法(如在spring-cloud-config
github上
讨论的):

@Component
@ConfigurationProperties("ignored")
@RefreshScope
public class Config {
    private List<String> path;

    public List<String> getPath() {
        return path;
    }

    public void setPath(List<String> path) {
        this.path = path;
    }
}

由于@RefreshScope和之间存在某些代理问题,@ConfigurationProperties因此无法正常工作-
这两个注释均导致Bean代理彼此冲突。

因此,我从spring的角度开始研究它。propertySources可通过以下方式访问,Environment因此您可以通过以下方式访问和修改它们:

final String propertySourceName = "externalConfiguration"; 
// name of propertySource as defined by 
// @PropertySource(name = "externalConfiguration", value = "${application.config.location}")
ResourcePropertySource propertySource = new ResourcePropertySource(propertySourceName, new FileSystemResource(file));
MutablePropertySources sources = ctx.getEnvironment().getPropertySources();
sources.replace(propertySourceName, propertySource);

我的用例基于“用户编辑文件”,因此刷新的属性基于FileSystemWatcher,后者使propertySources发生了变化。为了使配置Bean正确提取源,该Bean的范围需要是一个原型-
在每次调用时都正确地重建。

完整示例可以参考。不包括任何配置服务器。希望能有所帮助

2020-05-30