【问题标题】:Spring @ConfigurationProperties not mapping list of objectsSpring @ConfigurationProperties 不映射对象列表
【发布时间】:2018-12-25 00:02:05
【问题描述】:

我在使用 spring 属性映射器时遇到了奇怪的问题。我有 yml 包含值列表。我想将其转换为构建应用程序的对象列表。所以,我使用了@ConfigurationProperties。有了这个,我可以映射简单的类型。当我将它用于复杂类型(对象列表)时,它失败了。也不例外,但是当我调试时值列表为零。请在下面找到 yml 和 java 文件。我尝试使用 spring 2.0.0,2.0.1,2.0.2,2.0.3 没有成功。任何人都可以解决它吗?

application.yml

acme:
  list:
    - name: my name
      description: my description
    - name: another name
      description: another description

AcmeProperties.java

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
@ConfigurationProperties("acme")
@PropertySource("classpath:configuration/yml/application.yml")
public class AcmeProperties {

    private final List<MyPojo> list = new ArrayList<>();

    public List<MyPojo> getList() {
        return this.list;
    }

    static class MyPojo {
        private String name;
        private String description;

        public String getName() {
            return name;
        }

        public String getDescription() {
            return description;
        }
    }
}

使用 setter 和 getter 方法:

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
@ConfigurationProperties(prefix = "acme")
@PropertySource("classpath:configuration/yml/application.yml")
public class AcmeProperties {

    private List<MyPojo> list;

    public List<MyPojo> getList() {
        return list;
    }

    public void setList(List<MyPojo> list) {
        this.list = list;
    }

    public static class MyPojo {
        private String name;
        private String description;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }
    }
}

这个类的用法:

@Autowired
public HomeController(AppProperties appProperties, AcmeProperties acmeProperties) {
    this.appProperties = appProperties;
    this.acmeProperties = acmeProperties;
}

【问题讨论】:

  • 可以试试public static class MyPojo,并把set方法放在上面。与list 相同:使其成为非最终的,不要初始化它,并为其设置一个设置器
  • @MrSpoon,没有成功
  • 我在 Spring Boot 应用程序中使用 setter 和 getter 尝试了您的代码,并且它有效......所以我怀疑问题出在这些类中。您不会手动或通过新创建和 AcmeProperties bean,对吗?春季启动版本?一个额外的信息。我省略了 @PropertySource("classpath:configuration/yml/application.yml") 我已将它放在资源文件夹中的 application.yml 中。您可以出于调试原因尝试吗?以防万一..
  • @Alexandros,我没有手动创建 AcmeProperties bean。我在我的控制器中自动连接了它。我用用法更新了我的问题,请检查。
  • @Alexandros,我使用的是 spring-boot 2.0.3。您可以在答案中发布您的更改吗?或用您的更改更新问题?

标签: java spring spring-boot yaml


【解决方案1】:

问题是PropertySource 仅支持属性文件,您无法从yml 文件中读取值。你可以像这样更新它:

@Component
@ConfigurationProperties("acme")
@PropertySource("classpath:/configuration/yml/test.properties")
class AcmeProperties {

configuration/yml/test.properties

acme.list[0].name=my name
acme.list[0].description=my description
acme.list[1].name=another name
acme.list[1].description=another description

并且代码应该可以工作。

【讨论】:

    【解决方案2】:

    根据Spring Boot documentation(重点是我的):

    24.6.4 YAML 缺点

    无法使用@PropertySource 注解加载 YAML 文件。 因此,如果您需要以这种方式加载值,则需要使用 属性文件。

    但是你向@PropertySource提供了一个yml文件:

    @Component
    @ConfigurationProperties(prefix = "acme")
    @PropertySource("classpath:configuration/yml/application.yml")
    public class AcmeProperties { ...}  
    

    所以你有两种可能:

    • 此 yml 文件是 Spring Boot 配置文件属性文件:在执行应用程序之前启用此配置文件,因此删除 @PropertySource
    • 此 yml 文件不是 Spring Boot 配置文件属性文件:使用属性文件而不是 yml 文件。

    【讨论】:

      【解决方案3】:

      试试 @ConfigurationProperties(prefix = "acme")

      基于: https://aykutakin.wordpress.com/2016/02/26/injecting-list-with-spring-from-yaml/

      【讨论】:

      • 是一样的。枚举的value()prefix 的别名
      • @James,没有成功
      • 哦,好吧,也许 .yml 格式是错误的。这个小男孩对这件事很敏感
      • 没有格式是好的,当我给出简单的类型时它会接受。
      • 我关注了这个link
      【解决方案4】:

      我认为问题是找不到@PropertySource("classpath:configuration/yml/application.yml") 中指定的资源。 - 尝试调试代码时犯了同样的错误..- 你能在里面设置一个断点吗 org.springframework.context.annotation.ConfigurationClassParser#processPropertySource 从返回的监视检查路径 this.resourceLoader.getResource(resolvedLocation).getFile().

      在我的情况下,我有:C:\Users\user12\Desktop\hibernate\out\production\classes\configuration\application.yml

      没有application.yml...

      我认为你没有看到异常,因为春天有 if (ignoreResourceNotFound) {..} else {throw ex} 在这个方法中

      【讨论】:

      • 如果找不到资源,spring 应用程序将无法运行。在我的本地,我可以运行应用程序并从 yml 文件中获取简单类型
      • @Component @ConfigurationProperties("acme") public class AcmeProperties { ... } 并在resources文件夹下添加一个application.yml。
      猜你喜欢
      • 1970-01-01
      • 2023-03-18
      • 2016-07-13
      • 2016-03-06
      • 2018-01-18
      • 1970-01-01
      • 1970-01-01
      • 2018-06-26
      • 2021-10-28
      相关资源
      最近更新 更多