0

我有一个application.yml包含以下内容的文件:

topics:
  input:
    - name: topic1
      partitions: 3
      replicas: 1
    - name: topic2
      partitions: 6
      replicas: 2

我希望能够在运行时更新或添加新的主题对象。

我尝试了以下方法来更新现有对象:

java -jar app.jar --topics.input[0].name="topicX"

以及将另一个对象添加到列表中的以下内容:

java -jar app.jar --topics.input[2].name="topicX" --topics.input[2].partitions=6 --topics.input[2].replicas=2

我通过以下方式访问属性:

@Component
@ConfigurationProperties(prefix = "topics")
@Validated
public class TopicsConfiguration {

  @NotEmpty
  @NotNull
  private List<TopicConfiguration> input = new ArrayList<>();

  public List<TopicConfiguration> getInputTopics() {
    return input;
  }

  public void setFacts(List<TopicConfiguration> input) {
    this.input = input;
  }

}

WhereTopicConfiguration只是一个列出了 3 个字段的 POJO。

当我不尝试在运行时修改任何属性对象时,这完全符合我的预期,但是我根本无法更新属性列表。当我尝试更新现有对象时,我得到一个 NPE。当我尝试将新对象添加到列表中时,我得到:

Property: topics.input[2].name
    Value: lmnop
    Origin: "topics.input[2].name" from property source "commandLineArgs"
    Reason: The elements [topics.input[2].name,topics.input[2].partitions,topics.input[2].replicas] were left unbound.

application.yml我只想知道是否有任何方法可以在运行时更新或添加元素到列表中,这样我的项目的用户如果想要更新此配置就不必进行修改。

4

2 回答 2

2

好的,所以我做了一些研究和一些测试,并得出以下结论:

您无法更新已定义的列表application.yml

如果你运行:

java -jar myApp.jar -my-list[2].name=foo

它会失败,因为只要你想传递列表,列表就会覆盖 application.yml 中的当前列表,并且当索引 0 和 1 处没有任何内容时,你试图传递列表中的第三项。

它不是一个动态列表,它是一个数组。

您需要传递整个列表:

java -jar myApp.jar -my-list[0].name=foo -my-list[1].name=bar -my-list[2].name=foobar 

因此,如果您要从 cmd 传入一个列表,则必须始终从头开始定义该列表。

于 2019-07-09T19:20:05.810 回答
0

因此,您想即时重新加载您application.propertiesapplication.ymlSpring Boot 应用程序,而无需将另一个代码提交到另一个部署?如果我理解这一点,那么这就是你如何做到的。

阅读这些链接,并在Spring Boot Actuator Reload Properties或上搜索更多信息Spring Scheduling。我们无法为您提供一个书面代码来使其正常工作,但有很多示例可供检查和尝试。

链接:

  1. 执行器刷新
  2. 春季调度

如果我是你,我会更喜欢 Actuator 方法,因为它可以避免混淆并且更干净。

于 2019-07-09T12:36:18.747 回答