一尘不染

Spring Boot-从application.yml注入映射

java spring

我有一个带有以下内容的Spring Boot应用程序application.yml-基本上是从这里获取的:

info:
   build:
      artifact: ${project.artifactId}
      name: ${project.name}
      description: ${project.description}
      version: ${project.version}

我可以注入特定的值,例如

@Value("${info.build.artifact}") String value

但是,我想注入整个地图,例如:

@Value("${info}") Map<String, Object> info

那(或类似的东西)可能吗?显然,我可以直接加载yaml,但是想知道Spring是否已经支持了某些东西。


阅读 547

收藏
2020-03-24

共3个答案

一尘不染

你可以使用插入地图@ConfigurationProperties:

import java.util.HashMap;
import java.util.Map;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableAutoConfiguration
@EnableConfigurationProperties
public class MapBindingSample {

    public static void main(String[] args) throws Exception {
        System.out.println(SpringApplication.run(MapBindingSample.class, args)
                .getBean(Test.class).getInfo());
    }

    @Bean
    @ConfigurationProperties
    public Test test() {
        return new Test();
    }

    public static class Test {

        private Map<String, Object> info = new HashMap<String, Object>();

        public Map<String, Object> getInfo() {
            return this.info;
        }
    }
}

使用问题中的yaml运行它会产生:

{build={artifact=${project.artifactId}, version=${project.version}, name=${project.name}, description=${project.description}}}

有多种选项可用于设置前缀,控制如何处理缺少的属性等。有关更多信息,请参见javadoc。

2020-03-24
一尘不染

下面的解决方案是@Andy Wilkinson解决方案的简写,除了它不必使用单独的类或在带@Bean注释的方法上。

application.yml:

input:
  name: raja
  age: 12
  somedata:
    abcd: 1 
    bcbd: 2
    cdbd: 3

SomeComponent.java:

@Component
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "input")
class SomeComponent {

    @Value("${input.name}")
    private String name;

    @Value("${input.age}")
    private Integer age;

    private HashMap<String, Integer> somedata;

    public HashMap<String, Integer> getSomedata() {
        return somedata;
    }

    public void setSomedata(HashMap<String, Integer> somedata) {
        this.somedata = somedata;
    }

}

我们可以将@Value注解和合并在一起@ConfigurationProperties,没有问题。但是,gettersetter很重要,@EnableConfigurationProperties必须使它们@ConfigurationProperties起作用。

我从@Szymon Stepniak提供的常规解决方案中尝试了此想法,认为这对某人有用。

2020-03-24
一尘不染

下面的解决方案是@Andy Wilkinson解决方案的简写,除了它不必使用单独的类或在带@Bean注释的方法上。

application.yml:

input:
  name: raja
  age: 12
  somedata:
    abcd: 1 
    bcbd: 2
    cdbd: 3

SomeComponent.java:

@Component
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "input")
class SomeComponent {

    @Value("${input.name}")
    private String name;

    @Value("${input.age}")
    private Integer age;

    private HashMap<String, Integer> somedata;

    public HashMap<String, Integer> getSomedata() {
        return somedata;
    }

    public void setSomedata(HashMap<String, Integer> somedata) {
        this.somedata = somedata;
    }

}

我们可以将@Value注解和合并在一起@ConfigurationProperties,没有问题。但是,gettersetter很重要,@EnableConfigurationProperties必须使它们@ConfigurationProperties起作用。

我从@Szymon Stepniak提供的常规解决方案中尝试了此想法,认为这对某人有用。

2020-10-16