Java Spring 引导:在没有 spring 云配置服务器的情况下重新加载配置
Java Spring Boot: Reload config without spring cloud config server
我正在尝试在运行时重新加载我的应用程序的配置。配置在 yaml 文件中,并且与 @ConfigurationProperties
的绑定按预期工作。接下来的事情是。我想在 yaml 更改后重新加载配置。或者更确切地说,我正在检查 @Scheduled
文件是否已更改。
我想避免 运行 第二台服务器来进行我的 Environment
更新。我有两个问题:
- 我该如何更新环境,
ConfigurableEnvironment
也许?
- 我如何传播这些?
Spring 云配置文档指出:
The EnvironmentChangeEvent
covers a large class of refresh use cases, as long as you can actually make a change to the Environment
and publish the event (those APIs are public and part of core Spring)
所以发布事件是有效的,但我不知道如何实际更新属性。
对此有很多讨论:如何在没有任何配置服务器的情况下刷新属性。 here 上有一个 Dave Syer post 带来了一些启发 - 但仍然不是不言自明的。
spring-boot/-cloud 最自然的方法如下(如 on 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的角度来看待它。可以通过 Environment
访问 propertySources,因此您可以通过
访问和修改它们
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);
我的用例基于 "user editing the file",因此刷新的属性基于 FileSystemWatcher,它改变了 propertySources。对于配置 bean 正确摄取的源,bean 的范围需要是一个原型——以便在每次调用时正确重建。
完整的例子是available as a gist。不包含任何配置服务器。希望有帮助
我正在尝试在运行时重新加载我的应用程序的配置。配置在 yaml 文件中,并且与 @ConfigurationProperties
的绑定按预期工作。接下来的事情是。我想在 yaml 更改后重新加载配置。或者更确切地说,我正在检查 @Scheduled
文件是否已更改。
我想避免 运行 第二台服务器来进行我的 Environment
更新。我有两个问题:
- 我该如何更新环境,
ConfigurableEnvironment
也许? - 我如何传播这些?
Spring 云配置文档指出:
The
EnvironmentChangeEvent
covers a large class of refresh use cases, as long as you can actually make a change to theEnvironment
and publish the event (those APIs are public and part of core Spring)
所以发布事件是有效的,但我不知道如何实际更新属性。
对此有很多讨论:如何在没有任何配置服务器的情况下刷新属性。 here 上有一个 Dave Syer post 带来了一些启发 - 但仍然不是不言自明的。
spring-boot/-cloud 最自然的方法如下(如 on 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的角度来看待它。可以通过 Environment
访问 propertySources,因此您可以通过
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);
我的用例基于 "user editing the file",因此刷新的属性基于 FileSystemWatcher,它改变了 propertySources。对于配置 bean 正确摄取的源,bean 的范围需要是一个原型——以便在每次调用时正确重建。
完整的例子是available as a gist。不包含任何配置服务器。希望有帮助