对于我的 Spring Boot 应用程序,我试图使用一个包含properties.topicsin列表的环境变量application.yml(请参阅下面的配置)。
properties:
topics:
- topic-01
- topic-02
- topic-03
Run Code Online (Sandbox Code Playgroud)
我使用配置文件来填充properties bean(参见这个spring文档),如下图
import java.util.ArrayList;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("properties")
public class ApplicationProperties {
private List<String> topics = new ArrayList<>();
public void setTopics(List<String> topics) {
this.topics = topics;
}
public List<String> getTopics() {
return this.topics;
}
}
Run Code Online (Sandbox Code Playgroud)
通过使用环境变量,我可以在不更改application.yml. 但是,到目前为止我能找到的所有示例仅适用于环境变量仅包含单个值的情况,而不是我的情况下的值集合。
编辑:
为了在@vancleff 发表评论后说清楚,我不需要将环境变量的值保存到application.yml.
另一个编辑:
我认为通过过度简化我的问题,我在脚下开枪。@LppEdd 答案适用于我的问题中给出的示例。但是,如果我需要更复杂的结构而不是简单的字符串主题名称集合,会发生什么情况。例如,像
properties:
topics:
-
name: topic-01
id: id-1
-
name: topic-02
id: id-2
-
name: topic-03
id: id-3
Run Code Online (Sandbox Code Playgroud)
Cor*_*gan 24
节目有点晚了,但是我遇到了同样的问题,这解决了
https://github.com/spring-projects/spring-boot/wiki/Relaxed-Binding-2.0#lists-1
MY_FOO_1_ = my.foo[1]
MY_FOO_1_BAR = my.foo[1].bar
MY_FOO_1_2_ = my.foo[1][2]`
Run Code Online (Sandbox Code Playgroud)
因此,对于问题中的示例:
properties:
topics:
-
name: topic-01
id: id-1
-
name: topic-02
id: id-2
-
name: topic-03
id: id-3
Run Code Online (Sandbox Code Playgroud)
环境变量应如下所示:
PROPERTIES_TOPICS_0_NAME=topic-01
PROPERTIES_TOPICS_0_ID=id-01
PROPERTIES_TOPICS_1_NAME=topic-02
PROPERTIES_TOPICS_1_ID=id-02
PROPERTIES_TOPICS_2_NAME=topic-03
PROPERTIES_TOPICS_2_ID=id-03
Run Code Online (Sandbox Code Playgroud)
建议,不要太复杂。
假设您希望该列表作为Environment变量。你可以使用它来设置
-Dtopics=topic-01,topic-02,topic-03
Run Code Online (Sandbox Code Playgroud)
然后您可以使用注入的EnvironmentBean 恢复它,并创建一个新的List<String>Bean
@Bean
@Qualifier("topics")
List<String> topics(final Environment environment) {
final var topics = environment.getProperty("topics", "");
return Arrays.asList(topics.split(","));
}
Run Code Online (Sandbox Code Playgroud)
从现在开始,就List可以了@Autowired。
您还可以考虑创建自定义限定符注释,也许@Topics。
然后
@Service
class TopicService {
@Topics
@Autowired
private List<String> topics;
...
}
Run Code Online (Sandbox Code Playgroud)
甚至
@Service
class TopicService {
private final List<String> topics;
TopicService(@Topics final List<String> topics) {
this.topics = topics;
}
...
}
Run Code Online (Sandbox Code Playgroud)
您可以做的是使用外部化文件。
将该文件的路径传递给环境参数。
-DtopicsPath=C:/whatever/path/file.json
Run Code Online (Sandbox Code Playgroud)
然后使用EnvironmentBean 来恢复该路径。读取文件内容并要求Jackson反序列化
您还需要创建一个简单的Topic类
public class Topic {
public String name;
public String id;
}
Run Code Online (Sandbox Code Playgroud)
它代表这个JSON数组的一个元素
[
{
"name": "topic-1",
"id": "id-1"
},
{
"name": "topic-2",
"id": "id-2"
}
]
Run Code Online (Sandbox Code Playgroud)
@Bean
List<Topic> topics(
final Environment environment,
final ObjectMapper objectMapper) throws IOException {
// Get the file path
final var topicsPath = environment.getProperty("topicsPath");
if (topicsPath == null) {
return Collections.emptyList();
}
// Read the file content
final var json = Files.readString(Paths.get(topicsPath));
// Convert the JSON to Java objects
final var topics = objectMapper.readValue(json, Topic[].class);
return Arrays.asList(topics);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11991 次 |
| 最近记录: |