我已经遍布stackoverflow和网络寻找解决方案。没有我见过的解决方案,因为可能没有任何帖子完全符合我的用例,其中包含文件内的列表以及对象结构。
这是一个样本作为yaml
teddy.list:
-
name: Red
price: Five
-
name: Blue
price: One
-
name: Yellow
price: Two
-
name: Green
price: Three
以下是与属性文件相同的示例
teddy.list[0].name=Red
teddy.list[0].price=Five
teddy.list[1].name=Blue
teddy.list[1].price=One
teddy.list[2].name=Yellow
teddy.list[2].price=Two
teddy.list[3].name=Green
teddy.list[3].price=Three
我希望能够将teddy.yml或teddy.properties文件提供给我的应用程序进行配置。
以下是我的课程:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
@Configuration
@PropertySource(name = "props", value = "classpath:teddy.yml", ignoreResourceNotFound = false)
@ConfigurationProperties(prefix = "teddy")
public class TeddyBearConfig {
@Autowired
Environment env;
@Value("${teddy.list}")
private TeddyBear[] teddyBears;
public TeddyBear[] getTeddyBears() {
return teddyBears;
}
public void setTeddyBears(TeddyBear[] teddyBears) {
this.teddyBears = teddyBears;
}
public static class TeddyBear {
private String name;
private String price;
public TeddyBear() {
}
public TeddyBear(String name, String price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
}
我尝试过这个设置,使用环境尝试访问属性,删除前缀,声明一个bean“PropertySourcesPlaceholderConfigurer”。
使用当前代码,spring抛出IllegalStateException,因为它无法将java.lang.string转换为我的TeddyBear类。
答案 0 :(得分:3)
这应该有效。
@Configuration
@PropertySource(name = "props", value = "classpath:teddy.properties", ignoreResourceNotFound = false)
@ConfigurationProperties(prefix = "teddy")
public class TeddyBearConfig {
private List<TeddyBear> list;
public List<TeddyBear> getList() {
return list;
}
public void setList(List<TeddyBear> list) {
this.list = list;
}
public static class TeddyBear {
private String name;
private String price;
public TeddyBear() {
}
public TeddyBear(String name, String price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
}
更新:
以上代码适用于您上面提供的属性文件。
如果您希望使用yml文件,则可以这样做。但有几点
你的yml结构不正确,应该是这样的
teddy:
list:
-
name: Red
price: Five
-
name: Blue
price: One
-
name: Yellow
price: Two
-
name: Green
price: Three
2。修复yml结构(以及TeddyBearConfig中的文件名)之后,您将看到springboot在启动时没有出现问题,但是如果TeddBearConfig中的列表变量为null。这是springboot通过@PropertySource
处理yml文件的方式中的一个错误。
3.如果您将此yml内容移至application.yml
并删除配置文件中的@PropertySource
行,您会发现一切正常。
答案 1 :(得分:0)
由于您使用的是ConfigurationProperties
注释,而不是
@Value("${teddy.list}")
private TeddyBear[] teddyBears;
你可以直接做
private List<TeddyBear> list;
无需@Value
注释。
此外,变量名称必须为list
,因为这是您提供给yml的内容。
答案 2 :(得分:0)
当心。取决于Spring版本,上面的代码可能不起作用!
这可能!
private List<TeddyBear> list = new ArrayList<>;
public List<TeddyBear> getList() {
return list;
}
窍门是Spring分解调用getList()并将TeddyBears添加到新的ArrayList中。在空指针上没有要添加的内容。抛弃吸气剂。未使用。
您只需要进一步:
@Autowired
TeddyBearConfig teddyBearConfig;
最后一句话:如果要在SpringBootTest下进行测试,则可能需要更多提示。
提供一个测试应用作为上下文。肯定有一种更优雅的方式,但是我这样做是这样的:
@SpringBootTest(classes = {TestApplication.class,..
@SpringBootApplication
public class TestApplication {
public static void main(String[] args) throws Throwable {
SpringApplication.run(TestApplication.class, args);
}
}
如果您的app.properties在TestSources路径下,请使用TestPropertySource:
@TestPropertySource(locations="classpath:application.properties")