我有一个带有属性形式的外部配置的应用程序。我希望应用程序对此类属性的更改做出反应,而无需重新启动或刷新整个上下文。
我不清楚我的选择是什么。
人工示例:应用程序实现了一项服务,该服务接收请求并决定是将请求排队还是拒绝。队列的最大大小是一个属性。
final int queueMaxSize = queueProperties.getMaxSize();
if (queue.size() >= queueMaxSize) { //reject }
QueueProperties
是用@ConfigurationProperties注释的类。
@ConfigurationProperties(prefix = "myapp.limits.queue")
@Getter
@Setter
public class QueueProperties {
public int maxSize = 10;
}
这可以使我通过系统属性,配置文件等控制行为。 但是,我希望能够在不释放/部署/重新启动/刷新应用程序的情况下更改此值。
我的应用程序已使用Archaius。
如果我使用内部基础结构为此属性推送新值,则可以看到Spring Environment应用程序确实收到了新值。
(例如/admin/env
反映了价值并动态变化)。
我不清楚的部分是:如何使我的服务对环境价值的变化做出反应?
我发现了两种方法,但是它们看起来很毛茸茸,我想知道是否还有更好的选择。我希望这是Spring生态系统中一流解决方案的常见问题。
棘手的解决方案#1:
@Bean
@Scope("prototype")
@ConfigurationProperties(prefix = "myapp.limits.queue")
QueueProperties queueProperties() {
return new QueueProperties();
}
使用属性Provider<QueueProperties>
将其注入到服务中,并将其用作queuePropertiesProvider.get().getMaxSize()
。
这有效,但有一些副作用,我不喜欢:
ConfigurationProperties
注释已从类移至bean定义QueueProperties
对象,并将其绑定到每个传入请求的值上get()
棘手的解决方案2:
不要用ConfigurationProperties
注释我的属性类,在构造时注入Spring环境。像这样实现吸气剂:
int getMaxSize() {
return environment.getProperty("myapp.limits.queue", 10);
}
这在行为方面也可以。然而
-这没有注释为属性(与这个大型项目中的其他属性类不同,它很难找到)
-该课程未显示在/admin/configprops
棘手的解决方案3:
安排一个定期任务,该任务使用Environment
更新我的单例QueueProperties
bean。
还有其他想法/建议/指标吗? 有没有一种规范/推荐的方法来做到这一点,而又没有我上面解决方案的缺点?