Spring Boot中动态属性的选项

时间:2018-12-20 22:19:08

标签: java spring spring-boot configuration

我有一个带有属性形式的外部配置的应用程序。我希望应用程序对此类属性的更改做出反应,而无需重新启动或刷新整个上下文。

我不清楚我的选择是什么。

人工示例:应用程序实现了一项服务,该服务接收请求并决定是将请求排队还是拒绝。队列的最大大小是一个属性。

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。

还有其他想法/建议/指标吗? 有没有一种规范/推荐的方法来做到这一点,而又没有我上面解决方案的缺点?

0 个答案:

没有答案