Переменные среды для списка в конфигурации весенней загрузки - PullRequest
1 голос
/ 11 марта 2019

Для моего приложения Spring Boot я пытаюсь использовать переменную среды, которая содержит список properties.topics в application.yml (см. Конфигурацию ниже).

properties:
      topics:
        - topic-01
        - topic-02
        - topic-03

Я использую файл конфигурации для заполнения свойств объекта (см. Эту весеннюю документацию ), как показано ниже

import java.util.ArrayList;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties("properties")
public class ApplicationProperties {
  private List<String> topics = new ArrayList<>();
  public void setTopics(List<String> topics) {
     this.topics = topics;
  }
  public List<String> getTopics() {
     return this.topics;
  }
}

С использованием переменной среды,Я могу изменить содержимое списка без изменения application.yml.Тем не менее, все примеры, которые я смог найти до сих пор только для случаев, когда переменная среды содержит только одно значение, а не набор значений в моем случае.

Редактировать:

Чтобы сделать это понятным после комментария @ vancleff, мне не нужно сохранять значения переменной среды в application.yml.

Другое редактирование:

Я думаю, что, упрощая мой вопрос, я стреляю себе в ногу.Ответ @LppEdd хорошо работает с примером, приведенным в моем вопросе.Однако что произойдет, если вместо набора простых строковых названий тем мне понадобится более сложная структура.Например, что-то вроде

properties:
  topics:
    - 
      name: topic-01
      id: id-1
    - 
      name: topic-02
      id: id-2
    - 
      name: topic-03
      id: id-3

1 Ответ

1 голос
/ 11 марта 2019

Предложение, не усложняйте.

Скажите, что вы хотите, чтобы этот список был Environment переменной.Вы установили бы его с помощью

-Dtopics=topic-01,topic-02,topic-03

Затем вы можете восстановить его с помощью введенного Environment Бина и создать новый List<String> Бин

@Bean
@Qualifier("topics")
List<String> topics(final Environment environment) {
    final var topics = environment.getProperty("topics", "");
    return Arrays.asList(topics.split(","));
}

С этого моментаList может быть @Autowired.
Вы также можете рассмотреть возможность создания своей пользовательской аннотации квалификатора, может быть @Topics.

Тогда

@Service
class TopicService {
   @Topics
   @Autowired
   private List<String> topics;

   ...
}

Или даже

@Service
class TopicService {
   private final List<String> topics;

   TopicService(@Topics final List<String> topics) {
      this.topics = topics;
   }

   ...
}

То, что вы можете сделать, это использовать внешний файл.
Передать в параметры среды путь к этому файлу.

-DtopicsPath=C:/whatever/path/file.json

Чем использовать бин Environment для восстановления этогодорожка.Прочитайте содержимое файла и попросите Jackson десериализовать его

Вам также необходимо создать простой Topic класс

public class Topic {
    public String name;
    public String id;
}

, представляющий элемент этого массива JSON

[
    {
        "name": "topic-1",
        "id": "id-1"
    },
    {
        "name": "topic-2",
        "id": "id-2"
    }
]

@Bean
List<Topic> topics(
        final Environment environment,
        final ObjectMapper objectMapper) throws IOException {
    // Get the file path
    final var topicsPath = environment.getProperty("topicsPath");

    if (topicsPath == null) {
        return Collections.emptyList();
    }

    // Read the file content
    final var json = Files.readString(Paths.get(topicsPath));

    // Convert the JSON to Java objects
    final var topics = objectMapper.readValue(json, Topic[].class);
    return Arrays.asList(topics);
}

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...