有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Spring Boot中动态属性的java选项

我有一个应用程序,它以属性的形式具有一些外部化的配置。我希望应用程序能够在不重新启动或完全刷新上下文的情况下对此类属性的更改做出反应

我不清楚我的选择是什么

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

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环境确实收到了新值。 (例如,/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环境。实现getter,如下所示:

int getMaxSize() {
   return environment.getProperty("myapp.limits.queue", 10);
}

就行为而言,这也行。然而 -这不是注释为property(与这个大型项目中的其他properties类不同,这使得它更难找到) -这个类不会出现在/admin/configprops

黑客解决方案#3:

安排使用Environment更新我的单例QueuePropertiesbean的定期任务

还有什么想法/建议/建议吗? 是否有一种规范/推荐的方法可以做到这一点,而不存在上述解决方案的缺点


共 (0) 个答案