Spring Boot-вставить карту из приложения.в формате YML



у меня есть 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 напрямую, но мне было интересно, есть ли что-то уже поддержанное весной.

829   5  

5 ответов:

вы можете иметь карту вводится с помощью @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}}}

существуют различные варианты установки префикса, управления обработкой отсутствующих свойств и т. д. Смотрите документация для получения дополнительной информации.

ниже решение является сокращением для решения @Andy Wilkinson, за исключением того, что он не должен использовать отдельный класс или на @Bean аннотированный метод.

приложение.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, нет вопросов. Но геттеры и сеттеры важны и @EnableConfigurationProperties должен иметь @ConfigurationProperties на работу.

я попробовал эту идею из заводное решение, предоставленное @Szymon Stepniak, подумал, что это будет полезно для кого-то.

сегодня я столкнулся с той же проблемой, но, к сожалению, решение Энди не сработало для меня. В Весенней Загрузке 1.2.1.Отпустите это еще проще, но вы должны быть в курсе нескольких вещей.

вот интересная часть от моего application.yml:

oauth:
  providers:
    google:
     api: org.scribe.builder.api.Google2Api
     key: api_key
     secret: api_secret
     callback: http://callback.your.host/oauth/google

providers карта содержит только одну запись карты, Моя цель-обеспечить динамическую конфигурацию для других поставщиков 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 не был инициализирован. Я попробовал решение, предложенное Энди, но оно не сработало. Я использую в Groovy в этом приложении, поэтому я решил удалить private и пусть Groovy генерирует геттер и сеттер. Так что мой код выглядел так:

@Service
@ConfigurationProperties(prefix = 'oauth')
class OAuth2ProvidersService implements InitializingBean {

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

    @Override
    void afterPropertiesSet() throws Exception {
       initialize()
    }

    private void initialize() {
       //....
    }
}

после этого небольшого изменения все работало.

хотя там есть одна вещь, о которой стоит упомянуть. После того, как я заставлю его работать, я решил сделать это поле private и предоставить сеттер с прямым типом аргумента в методе сеттера. К сожалению, это не сработает. Это вызывает 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?

имейте это в виду, если вы используете Groovy в своем приложении Spring Boot.

foo.bars.one.counter=1
foo.bars.one.active=false
foo.bars[two].id=IdOfBarWithKeyTwo

public class Foo {

  private Map<String, Bar> bars = new HashMap<>();

  public Map<String, Bar> getBars() { .... }
}

https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-Configuration-Binding

для получения карты из конфигурации вам понадобится класс конфигурации. @ Value аннотация не будет делать трюк, к сожалению.

приложение.в формате YML

entries:
  map:
     key1: value1
     key2: value2

класса конфигурации:

@Component
    @ConfigurationProperties("entries")
    @Getter
    @Setter
    public static class MyConfig {
        private Map<String, String> map;
    }

Comments

    Ничего не найдено.