我有一个项目,我想配置字符串键控的“组” 字符串数组的字符串键控“命令”。也就是说,我想 能够在config.yml中表达类似下面的内容,以及 通过@ConfigurationProperties(prefix =“config.base”)消费:
---
config:
base:
"bin group":
- "Directory Listing": ["/bin/ls", "-la"]
- "Server Date/Time": ["/bin/date", "-u"]
"usr/bin group":
- "Find .txt Files": ["/usr/bin/find", ".", "-name", "*.txt"]
"usr/local/bin group":
- "Tree Listing": ["/usr/local/bin/tree"]
理想情况下,我希望@ConfigurationProperties对象为LinkedHashMap<String, LinkedHashMap<String, String[]>>
但我无法弄清楚如何做到这一点。或者任何合理接近的东西。 我得到的最接近的如下:
package us.w7tek.bug;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;
import javax.annotation.PostConstruct;
import java.util.LinkedHashMap;
@EnableConfigurationProperties
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
@ConfigurationProperties("someConfig")
@Bean
public ExternalizedConfig externalizedConfig() { return new ExternalizedConfig(); }
public static class ExternalizedConfig extends LinkedHashMap<String, String[]> {
// oops, @ConfigurationProperties ends up putting LinkedHashMap<String, String> in the values of the top-level mapping,
// and that second-level LinkedHashMap has keys that could have come from Integer#toString
}
@Controller
public static class ControllerThatConsumesConfig {
private static final String A_KEY_THAT_COULDNT_BE_A_PROPERTY_NAME = "this == config cannot be expressed as a bean with properties, because the keys cannot be made into Java language identifiers for bean property setters and getters";
@Autowired
ExternalizedConfig config;
@PostConstruct
void init() {
String[] strings = config.get(A_KEY_THAT_COULDNT_BE_A_PROPERTY_NAME); // ClassCastException occurs here
// doesn't have to occur in @PostConstruct, that was just a convenient place for my demo.
}
}
}
在项目中使用以下示例application.yml
:
---
someConfig:
"this is a key": ["this", "value", "is", "not", "an", "String[]"]
"this is another key": ["it", "is", "deserialized", "as", "LinkedHashMap", "having", "keys", "like", "\"0\"", "and", "\"1\"", "etc."]
"this == config cannot be expressed as a bean with properties, because the keys cannot be made into Java language identifiers for bean property setters and getters": ["thereby", "subverting", "Java's", "static", "typing", "and", "resulting", "in", "ClassCastException", "at", "runtime"]
如评论中所示,当Spring Boot @ConfigurationProperties
绑定器创建LinkedHashMap<String, LinkedHashMap<String, LinkedHashMap<String, String>>>
类型的对象并将其放在config
字段中时,该代码会爆炸。当然,只要任何方法根据其静态声明的类型访问config
,就会出现ClassCastException
。我不确定是否认为这是@ConfigurationProperties
使用的属性绑定器代码的错误,或者只是我的严重误解。我认为上面的代码是展示问题的最简单的代码。也可以在https://github.com/w7tek/demo-configproperties-bug.git找到,以防有人想编译并运行以查看堆栈跟踪。
有没有人有@ConfigurationProperties
收藏品的例子?通过简单地将声明的类型与Spring反序列化的实际类型相匹配,我可以从我所处的位置看到前进的方向,但最终使用起来非常不方便。我真的希望将此配置的最内层值作为List&lt;&gt;或数组类型,如果可能的话,但我无法弄清楚如何。
答案 0 :(得分:1)
这是您需要的:
不要使用tab,每个内部元素使用2个空格。
config:
base:
"bin group":
"Directory Listing": ["/bin/ls", "-la"]
"Server Date/Time": ["/bin/date", "-u"]
"usr/bin group":
"Find txt Files": ["/usr/bin/find", ".", "-name", "*.txt"]
"usr/local/bin group":
"Tree Listing": ["/usr/local/bin/tree"]
这是Configuration类:
@Configuration
@ConfigurationProperties(prefix = "config")
public class Conf_Test {
private LinkedHashMap<String, LinkedHashMap<String, List<String>>> base;
public LinkedHashMap<String, LinkedHashMap<String, List<String>>> getBase() {
return base;
}
public void setBase(LinkedHashMap<String, LinkedHashMap<String, List<String>>> base) {
this.base = base;
}
}
显然,你不能使用&#34;。&#34;在地图键内部,它只是剪切了键,所以我删除了&#34;查找.txt文件&#34;键。另外,spring-boot不支持map中的自动groving数组,因此现在不能使用String []但list正在运行。