简体   繁体   中英

Spring @ConfigurationProperties not mapping list of objects

I am facing strange issue with spring property mapper. I have yml contains list of values. I want convert that to list of object why building application. So, i used @ConfigurationProperties. With this i am able to map simple types. when i use this to complex type(list of objects) it failed. No exception, but values list is zero when i debug. please find below yml and java files. I tried with spring 2.0.0,2.0.1,2.0.2,2.0.3 No success. Can any one have idea to fix it?

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;
        }
    }
}

With setter and getter methods:

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;
        }
    }
}

Usage of this class:

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

The problem is PropertySource only support the properties file, you cannot read the value from yml file. you can update it like:

@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

and the code should works.

According to the Spring Boot documentation (emphasis is mine) :

24.6.4 YAML Shortcomings

YAML files cannot be loaded by using the @PropertySource annotation . So, in the case that you need to load values that way, you need to use a properties file.

But you provided a yml file to @PropertySource :

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

So you have two possibilities :

  • this yml file is a Spring Boot profile properties file : enable this profile before executing the application and so remove @PropertySource
  • this yml file is not a Spring Boot profile properties file : use a properties file instead of a yml file.

Try with @ConfigurationProperties(prefix = "acme")

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

I think problem is that resource is not found as specified at @PropertySource("classpath:configuration/yml/application.yml"). -made the same mistake when tried to debug your code..- Could you please put a break point in org.springframework.context.annotation.ConfigurationClassParser#processPropertySource with watch check path returned from this.resourceLoader.getResource(resolvedLocation).getFile().

In my case i have: C:\\Users\\user12\\Desktop\\hibernate\\out\\production\\classes\\configuration\\application.yml

there there is not application.yml...

I think you do not see exception because spring has if (ignoreResourceNotFound) {..} else {throw ex} in this method

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM