我正在尝试在运行时重新加载应用程序的配置。该配置位于yaml文件中,并且@ConfigurationProperties按预期进行绑定。接下来是。yaml更改后,我想重新加载配置。或更确切地说,我正在检查@Scheduled文件是否已更改。
@ConfigurationProperties
@Scheduled
我想避免运行第二台服务器进行Environment更新。我有两个问题:
Environment
ConfigurableEnvironment
Spring Cloud配置文档说明:
EnvironmentChangeEvent只要您可以实际更改Environment和发布事件(这些API是公共的并且是Spring核心的一部分),本章就涵盖了一大类刷新用例。
EnvironmentChangeEvent
因此,发布事件是可行的,但是我不了解如何实际更新属性。
关于这一点,有很多讨论:如何在没有任何配置服务器的情况下刷新属性。此处有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代理彼此冲突。
@RefreshScope
因此,我从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的范围需要是一个原型- 在每次调用时都正确地重建。
完整示例可以参考。不包括任何配置服务器。希望能有所帮助