为了账号安全,请及时绑定邮箱和手机立即绑定

Spring Boot-从application.yml注入映射

/ 猿问

Spring Boot-从application.yml注入映射

梵蒂冈之花 2019-11-13 15:25:42

我有一个带有以下内容的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是否已经支持了某些东西。


查看完整描述

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。


查看完整回答
反对 回复 2019-11-13
?
呼如林

下面的解决方案是@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,没有问题。但是,getter和setter很重要,@EnableConfigurationProperties必须使它们@ConfigurationProperties起作用。


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


查看完整回答
反对 回复 2019-11-13
?
萧十郎

今天,我遇到了同样的问题,但是不幸的是,安迪的解决方案对我不起作用。在Spring Boot 1.2.1.RELEASE中,它甚至更容易,但是您必须了解一些事情。


这是我的有趣部分application.yml:


oauth:

  providers:

    google:

     api: org.scribe.builder.api.Google2Api

     key: api_key

     secret: api_secret

     callback: http://callback.your.host/oauth/google

providersmap仅包含一个map条目,我的目标是为其他OAuth提供程序提供动态配置。我想将此地图注入到服务中,该服务将基于此yaml文件中提供的配置来初始化服务。我最初的实现是:


@Service

@ConfigurationProperties(prefix = 'oauth')

class OAuth2ProvidersService implements InitializingBean {


    private Map<String, Map<String, String>> providers = [:]


    @Override

    void afterPropertiesSet() throws Exception {

       initialize()

    }


    private void initialize() {

       //....

    }

}

启动应用程序后,providers映射OAuth2ProvidersService未初始化。我尝试了Andy建议的解决方案,但效果不佳。我在该应用程序中使用了Groovy,所以我决定删除private并让Groovy生成getter和setter。所以我的代码看起来像这样:


@Service

@ConfigurationProperties(prefix = 'oauth')

class OAuth2ProvidersService implements InitializingBean {


    Map<String, Map<String, String>> providers = [:]


    @Override

    void afterPropertiesSet() throws Exception {

       initialize()

    }


    private void initialize() {

       //....

    }

}

经过那一次小小的改动,一切正常。


尽管有一件事可能值得一提。在使其工作之后,我决定创建此字段,private并在setter方法中为setter提供直接参数类型。不幸的是,它不会起作用。它导致以下org.springframework.beans.NotWritablePropertyException消息:


Invalid property 'providers[google]' of bean class [com.zinvoice.user.service.OAuth2ProvidersService]: Cannot access indexed value in property referenced in indexed property path 'providers[google]'; nested exception is org.springframework.beans.NotReadablePropertyException: Invalid property 'providers[google]' of bean class [com.zinvoice.user.service.OAuth2ProvidersService]: Bean property 'providers[google]' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?

如果在Spring Boot应用程序中使用Groovy,请记住这一点。


查看完整回答
反对 回复 2019-11-13

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信