我有一个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;
}
}
TopicConfiguration
只是列出了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
。
答案 0 :(得分:1)
okey,所以我做了一些研究和测试,并提出了以下建议:
您无法更新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中传递列表,则必须始终从头开始定义列表。
答案 1 :(得分:0)
因此,您想动态地在Spring Boot应用程序中重新加载application.properties
或application.yml
,而不必使另一个代码提交到另一个部署中吗?如果我了解的没错,那么这就是您的方法。
阅读这些链接,并在Spring Boot Actuator Reload Properties
或Spring Scheduling
上搜索更多Google链接。我们无法为您提供经过编写的代码来使其正常工作,但是有很多示例可供研究和尝试。
链接:
如果我是您,我希望使用Actuator方法,因为它可以避免混乱并且更干净。