【问题标题】:Yaml properties not loaded in springboot未在 Spring Boot 中加载 Yaml 属性
【发布时间】:2022-01-01 21:37:05
【问题描述】:

我想使用 application.yml 而不是 application.properties

我关注了:https://docs.spring.io/spring-boot/docs/2.1.13.RELEASE/reference/html/boot-features-external-config.html

我正在使用:

  • SpringBoot 2.6.2
  • Java 17
  • Gradle 7.3.2

我的 MCVE: https://github.com/OldEngineer1911/demo1

问题是:未加载属性。有人可以帮忙吗?

【问题讨论】:

    标签: spring-boot configuration java-17


    【解决方案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;
        }
    }
    

    错误出现在您的 main 方法的 Products products = new Products(); 行中。您不会从 Spring 上下文中检索 bean,而是在 JVM 中自己创建它。因此它就像你创建的那样是空的。

    阅读更多内容以了解 Spring 如何为您的 Spring bean 使用代理,而不是您编写的实际类。

    您需要的是以下内容

    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 序列化的复杂对象数组。检查我在this SO thread中的意思

    考虑到您没有自定义对象列表,但原始List&lt;String&gt; 您的application.yml 应采用以下形式

    products: first,second
    

    【讨论】:

    • 感谢您的回复!我尝试(可以在此处看到:github.com/OldEngineer1911/demo1/blob/master/src/main/java/com/…)应用建议的解决方案,但它不会更改输出...不显示来自属性文件的变量。
    • @OldEngineer 检查更新的答案,我发现了错误
    • 感谢您的更新!但它仍然不起作用。我应用了第二次修复,但该属性仍未加载。
    • @OldEngineer 尝试在 Products.class 中从 private List&lt;String&gt; products = new ArrayList&lt;&gt;();`` change it into private List products 进行另一项更改;` 以便 spring 进行初始化,而不是您手动进行
    • 我得到:NPE:无法调用“java.util.List.size()”,因为“productsFromApplicationYml”为空。看起来spring没有初始化它。不知道为什么,应该是根据文档(上面提到的)。
    【解决方案2】:

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

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

    是必需的,但其余的都是可选的(可以用 yml 两种方式编写 List)。解决方案是使用嵌套产品修复 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)。无论如何,它仍然可以改进 - 不知道为什么我需要嵌套产品。

    【讨论】:

      猜你喜欢
      • 2019-04-13
      • 2019-10-18
      • 2019-08-09
      • 1970-01-01
      • 2014-12-21
      • 2018-06-25
      • 1970-01-01
      • 2018-10-13
      • 1970-01-01
      相关资源
      最近更新 更多