Spring Boot中未加载YAML属性。

3
2个回答

1
你有以下代码
@SpringBootApplication
public class Demo1Application {

    public static void main(String[] args) {
        SpringApplication.run(Demo1Application.class, args);
        Products products = new Products();  <---------------------------------ERROR!!!
        List<String> productsFromApplicationYml = products.getProducts();

        System.out.println(productsFromApplicationYml.size()); // I would like to see 2
        products.getProducts().forEach(System.out::println); // I would like to see "first" and "second"
    }



@Component
@ConfigurationProperties(prefix="products")
public class Products {
    private final List<String> products = new ArrayList<>();

    public List<String> getProducts() {
        return products;
    }
}

错误在于您主方法的代码行 Products products = new Products();。您没有从Spring上下文中检索bean,而是在JVM中自己创建了它。因此,它就像您创建的空对象一样。

继续阅读以了解Spring如何为您的Spring beans使用代理而不是您编写的实际类。

您需要的是以下内容:

public static void main(String[] args) {
  ApplicationContext app = SpringApplication.run(Demo1Application.class, args)

  Products products = app.getBean(Products.class); <---Retrieve the Proxy instance from Spring Context

  List<String> productsFromApplicationYml = products.getProducts();
  System.out.println(productsFromApplicationYml.size())

编辑:

你的application.yml文件配置错误。

products:
  - first
  - second

符号-用于复杂对象的数组,Spring将尝试从application.yml中进行序列化。请在此 SO 线程中查看我的意思。
考虑到您没有自定义对象列表而是一个原始的List<String>,您的application.yml应该采用以下形式。
products: first,second

感谢您的回复!我尝试了(可以在这里看到:https://github.com/OldEngineer1911/demo1/blob/master/src/main/java/com/example/demo/Demo1Application.java)应用所提出的解决方案,但它并没有改变输出...属性文件中的变量未显示。 - Dominik
@OldEngineer,请检查更新后的答案,我已经找到了错误。 - Panagiotis Bougioukos
我得到了以下错误信息:NPE: 无法调用“java.util.List.size()”,因为“productsFromApplicationYml”为空。看起来Spring没有初始化它。不知道为什么,根据文档(如上所述)应该被初始化。 - Dominik
@OldEngineer 试着在 @SpringBootApplication 下也包括 @EnableConfigurationProperties(Products.class) - Panagiotis Bougioukos
NoUniqueBeanDefinitionException: 找不到类型为 'com.example.demo.Products' 的限定bean:期望只有一个匹配的bean,但找到了2个:products、products-com.example.demo.Products。我已经尝试过注释的调整,但没有成功。 - Dominik
显示剩余2条评论

0

"@Panagiotis Bougiokos" 的解决方案部分正确:

Products products = app.getBean(Products.class); <---Retrieve the Proxy instance from Spring Context

这是必要的,但其余部分是可选的(可以用yml两种方式编写列表)。解决方案是使用嵌套产品修复yml文件:

products:
  products:
    - 'first'
    - 'second'

并且为产品添加setter方法:
@Component
@ConfigurationProperties(prefix="products")
public class Products {
    private List<String> products;

    public List<String> getProducts() {
        return products;
    }

    public void setProducts(List<String> products) {
        this.products = products;
    }
}

这是一个可行的解决方案(每个人都可以在问题中提到的Github上进行检查)。无论如何,它仍然可以改进 - 不知道为什么需要嵌套产品。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接