preface

When I did a little demo, I did an example where I wanted to put some data into properties in a configuration class at runtime, and I thought that I could map the data configured by YAML to properties in an entity class, and I wondered if I could map it that way.

case

application.yml

xxx:
  list: aaaaa
Copy the code

xxxConfig

@Configuration  // Declare this a configuration class
@ConfigurationProperties(prefix = "xxx")  // In application.yml, data prefixed with XXX is automatically matched
public class xxxConfig {
    private String list;
  	
  	// The set method is used here.
  	// Automatically map data to @configurationProperties (prefix = "XXX ")
    public void setList(String list) {
        this.list = list;
    }
  	
  	// For output effects
    @Override
    public String toString(a) {
        return "xxxConfig{" +
                "list='" + list + '\' ' +
                '} '; }}Copy the code

The test class

@SpringBootTest
public class Test {
    @Autowired
    private xxxConfig config;

    @Test
    void test(a){ System.out.println(config.toString()); }}Copy the code

The final output

xxxConfig{list='aaaaa'}
Copy the code

I can see that there is no problem with the mapped data, but I have a problem with writing a set method in a configuration class to inject auto-mapped data.

And then I realized that there’s also an @Value annotation that can be injected without having to write a set method in your code

XxxConfig transformation

@Configuration
public class xxxConfig {
    @Value("${xxx.list}")
    private String list;
    @Override
    public String toString(a) {
        return "xxxConfig{" +
                "list='" + list + '\' ' +
                '} '; }}Copy the code

application.yml

xxx:
  list: abab
Copy the code

The test results

xxxConfig{list='abab'}
Copy the code

You can see that there is no problem with this, and when I inject data into a List or other complex type, a type cannot be resolved

xxxConfig

@Configuration
public class xxxConfig {
    @Value("${xxx.list}")
    private List<String> list;
    @Override
    public String toString(a) {
        return "xxxConfig{" +
                "list='" + list + '\' ' +
                '} '; }}Copy the code

abnormal

Abnormal content

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xxxConfig': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'xxx.list' in value "${xxx.list}"
Copy the code

So here I quickly opened my universal Baidu, the majority of netizens to see the solution.

The solution

Inject List format

xxxConfig

@Configuration
public class xxxConfig {
    @Value("#{'${xxx.list}'.split(',')}")
    private List<String> list;
    @Override
    public String toString(a) {
        return "xxxConfig{" +
                "list='" + list + '\' ' +
                '} '; }}Copy the code

application.yaml

xxx:
  list: 1, 2, 3
Copy the code

The test results

XxxConfig {list = [1, 2, 3]}Copy the code

Actually write this format @ Value (” # {‘ ${XXX. List}. The split (‘ – ‘)} “), and this is the SpEL expression way

Inject Map format

xxxConfig

@Configuration
public class xxxConfig {
    @Value("#{'${xxx.list}'.split(',')}")
    private List<String> list;

    @Value("#{${xxx.map}}")
    private Map<String,Object> map;

    @Override
    public String toString(a) {
        return "xxxConfig{" +
                "list=" + list +
                ", map=" + map +
                '} '; }}Copy the code

application.yaml

xxx:
  list: 1, 2, 3
  map: "{key1: 'value1', key2: 'value2'}"
Copy the code

The test results

XxxConfig {list = [1, 2, 3], the map = {key1 = value1, key2 = value2}}Copy the code

summary

Through @ the Value form of the mapping List or Map types of data I also is the first time, but I feel there is no need this off, had a complexity is not very troublesome thing, especially complicated by such a change, you can’t use this approach in the List of objects and play, so I personally feel this is very inconvenient!!!!!!

Note: @ConfigurationProperties(prefix = “XXX “) uses this form of mapping property values with the corresponding set method and the class must be in the Spring container.

advice

Go to the Internet to see how the underlying @value is implemented, not only to see, their own point into the source code to study their own use of Debug step by step to see, @value Value is the use of Spring SpEL expression also have to see the basic syntax.

Throw in chicken soup


Want your life to be different and it’s not so bad right now, so stick with everything you do. Want your life to be different and it’s not so bad right now, so stick with everything you do.