【问题标题】:How to read properties from application.yml file in spring-boot application如何从 spring-boot 应用程序中的 application.yml 文件中读取属性
【发布时间】:2020-01-22 15:47:56
【问题描述】:

我的应用程序具有存储在 applicaion.yml 文件中的嵌套属性。
我想在应用程序启动时将这些属性映射到 POJO

Application.yml

    demo:
     - A:
       - type: A
         prop1: 1
         prop2: 2
         proop3: 3
       - type: B
         prop1: 1
         prop2: 2
         proop3: 3
     - B:
       - type: A
         prop1: 1
         prop2: 2
         proop3: 3
       - type: B
         prop1: 1
         prop2: 2
         proop3: 3

为了实现这一点,我使用以下注释:

@配置
@EnableConfigurationProperties
@ConfigurationProperties("demo")

课堂演示:

@Configuration
@EnableConfigurationProperties
@ConfigurationProperties("demo")
public class Demo {
    @JsonProperty("A")
    private List<A> a = null;
    @JsonProperty("B")
    private List<B> b = null;

    @JsonProperty("A")
    public List<A> getA() {
        return a;
    }

    @JsonProperty("A")
    public void setA(List<A> a) {
        this.a = a;
    }

    @JsonProperty("B")
    public List<B> getB() {
        return b;
    }

    @JsonProperty("B")
    public void setB(List<B> b) {
        this.b = b;
    }

    @Override
    public String toString() {
        return "Demo [a=" + a + ", b=" + b + "]";
    }   
}



A类:

public class A {

    @JsonProperty("type")
    private String type;
    @JsonProperty("prop1")
    private Integer prop1;
    @JsonProperty("prop2")
    private Integer prop2;
    @JsonProperty("proop3")
    private Integer proop3;

    @JsonProperty("type")
    public String getType() {
        return type;
    }

    @JsonProperty("type")
    public void setType(String type) {
        this.type = type;
    }

    @JsonProperty("prop1")
    public Integer getProp1() {
        return prop1;
    }

    @JsonProperty("prop1")
    public void setProp1(Integer prop1) {
        this.prop1 = prop1;
    }

    @JsonProperty("prop2")
    public Integer getProp2() {
        return prop2;
    }

    @JsonProperty("prop2")
    public void setProp2(Integer prop2) {
        this.prop2 = prop2;
    }

    @JsonProperty("proop3")
    public Integer getProop3() {
        return proop3;
    }

    @JsonProperty("proop3")
    public void setProop3(Integer proop3) {
        this.proop3 = proop3;
    }

    @Override
    public String toString() {
        return "A [type=" + type + ", prop1=" + prop1 + ", prop2=" + prop2 + ", proop3=" + proop3 + "]";
    }
}



B类

public class B {

    @JsonProperty("type")
    private String type;
    @JsonProperty("prop1")
    private Integer prop1;
    @JsonProperty("prop2")
    private Integer prop2;
    @JsonProperty("proop3")
    private Integer proop3;

    @JsonProperty("type")
    public String getType() {
        return type;
    }

    @JsonProperty("type")
    public void setType(String type) {
        this.type = type;
    }

    @JsonProperty("prop1")
    public Integer getProp1() {
        return prop1;
    }

    @JsonProperty("prop1")
    public void setProp1(Integer prop1) {
        this.prop1 = prop1;
    }

    @JsonProperty("prop2")
    public Integer getProp2() {
        return prop2;
    }

    @JsonProperty("prop2")
    public void setProp2(Integer prop2) {
        this.prop2 = prop2;
    }

    @JsonProperty("proop3")
    public Integer getProop3() {
        return proop3;
    }

    @JsonProperty("proop3")
    public void setProop3(Integer proop3) {
        this.proop3 = proop3;
    }

    @Override
    public String toString() {
        return "B [type=" + type + ", prop1=" + prop1 + ", prop2=" + prop2 + ", proop3=" + proop3 + "]";
    }
}



主类

@SpringBootApplication
@ComponentScan(basePackages = {"com.microservice.*"})
@EnableJpaRepositories("com.microservice.*")
@EntityScan("com.microservice.*")
public class MainApplication {  
    public static void main(String[] args) {
         SpringApplication app = new SpringApplication(MainApplication.class);
            app.run();
            System.out.println("step 1");
            Demo config = new Demo();
            System.out.println("name: " + config);
        }

        public void run(String... args) throws Exception {
            System.out.println("step 2");

        }
}

但我低于 o/p:
第 1 步
名称:演示 [a=null, b=null]

【问题讨论】:

标签: java spring-boot


【解决方案1】:

当您手动创建属性 POJO 的实例时,Spring 不知道它并且不会发生属性绑定。

 SpringApplication app = new SpringApplication(MainApplication.class);
    app.run();
    System.out.println("step 1");
    Demo config = new Demo(); // Not a Spring managed bean!
    System.out.println("name: " + config);
}

您可以将Demo 设为bean,而不是使用@EnableConfigurationProperties 注释配置,如Type-safe Configuration Properties 所示。

@Component
@ConfigurationProperties("demo")
public class Demo {
    ...
}

然后你可以从上下文中获取Demo bean:

@SpringBootApplication
public class MainApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(MainApplication.class, args);
        Demo demo = (Demo) context.getBean("demo");
        System.out.println(demo.getName());
    }
}

UPD: 'a' 和 'b' 之前不能有连字符:

demo:
  a:
    - type: A
      prop1: 1
      prop2: 2
      proop3: 3
    - type: B
      prop1: 1
      prop2: 2
      proop3: 3
  b:
    - type: B
      prop1: 1
      prop2: 2
      proop3: 3

UPD2: 回复评论。您可以使用 ObjectMapperDemo bean 构建 JSON:

@SpringBootApplication
public class MainApplication {

    @Bean
    public ObjectMapper objectMapper() {
        return new ObjectMapper();
    }

    public static void main(String[] args) throws JsonProcessingException {
        ...
        ObjectMapper objectMapper = (ObjectMapper) context.getBean("objectMapper");
        System.out.println(objectMapper.writeValueAsString(demo));
    }
}

有了spring-boot-starter-web,就不需要额外的依赖了。否则,您可以添加jackson

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.0.1</version>
</dependency>

【讨论】:

  • 对不起,我错过了 YAML 语法错误。 @Holinc 答案显示正确的答案。我也更新了答案。
  • 是的,这是可行的,但我正在查看 YAML 文件中的 json 下面。 : { "demo": [ { "A": [ { "type": "A", "prop1": 1, "prop2": 2, "proop3": 3 }, { "type": "B", “prop1”:1,“prop2”:2,“proop3”:3}]},{“B”:[{“type”:“A”,“prop1”:1,“prop2”:2,“proop3 ": 3 } ] } ] }
  • 问题是关于属性映射的。将 POJO 转换为 JSON 是另一大问题 :) 我添加了简单的示例,如何将 bean 打印为 JSON 字符串。希望对您有所帮助。
【解决方案2】:

您的yml 文件不正确。您可以在此处阅读Merging YAML lists,link 的参考。

我写了一个演示,它可以工作。

demo:
        a:
            b:
                prop1: prop1
                prop2: prop2
            blist:
                - prop1: prop1
                  prop2: prop2
        alist:
            - b:
                  prop1: prop1
                  prop2: prop2
              blist:
                  - prop1: prop1
                    prop2: prop2
            - b:
                  prop1: prop1
                  prop2: prop2

``

@ConfigurationProperties(prefix = "demo")
public class Demo {
    private A a;
    private List<A> alist;
    // omitted getter/setter
}

``

public class A {
    private B b;
    private List<B> blist;
    // omitted getter/setter
}

``

public class B {
    private String prop1;
    private String prop2;
    // omitted getter/setter
}

【讨论】:

  • 感谢您的回答,但为什么我的 YAML 结构不正确?
  • 我正在从我的 YAML 文件中寻找以下 JSON 结构:{ "demo": [ { "A": [ { "type": "A", "prop1": 1, "prop2 ": 2, "proop3": 3 }, { "type": "B", "prop1": 1, "prop2": 2, "proop3": 3 } ] }, { "B": [ { "type ": "A", "prop1": 1, "prop2": 2, "proop3": 3 } ] } ] }
  • JSON 中的 "A""B" 已被 @JsonProperty 注解重命名,ConfigurationProperties@JsonProperty 之间没有关系。 @mayank bisht
【解决方案3】:

如果您想从.yml.properties 文件中读取属性,我建议您创建一个可以称为PropertiesBooter 的类,您可以在其中保留从这些文件中检索到的所有值。要从属性文件中检索值,您可以编写

@Value("${value}")
private String 

【讨论】:

  • 感谢您的回答,但我不想那样做。我想将属性绑定到 POJO 文件。
【解决方案4】:

从 Mikhail 的回答中,只需使用 Jackson ObjectMapper 编写 json 即可获得 json 格式:

public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(YamlTestApplication.class, args);
        Demo demo = (Demo) context.getBean("demo");
        System.out.println("name: " + demo);

        ObjectMapper mapper = new ObjectMapper();
        try {
            String test = mapper.writeValueAsString(demo);
            System.out.println("json: "+test);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

输出:

name: Demo [a=[A [type=A, prop1=1, prop2=2, proop3=3], A [type=B, prop1=1, prop2=2, proop3=3]], b=[B [type=A, prop1=1, prop2=2, proop3=3], B [type=B, prop1=1, prop2=2, proop3=3]]]
json: {"A":[{"type":"A","prop1":1,"prop2":2,"proop3":3},{"type":"B","prop1":1,"prop2":2,"proop3":3}],"B":[{"type":"A","prop1":1,"prop2":2,"proop3":3},{"type":"B","prop1":1,"prop2":2,"proop3":3}]}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多