Можно ли использовать последовательность YAML со свойствами конфигурации Spring Boot? - PullRequest
1 голос
/ 28 апреля 2020

У меня есть требование, чтобы приложение Spring Boot загружало некоторую конфигурацию, которая идеально подходила бы для своего рода мини-таблицы. Почти вся конфигурация состоит из файлов свойств YAML, которые связаны с @ConfigurationProperties POJO, таким образом:

static class Entry {
    private final Terrain terrain;    // A simple enumeration
    private final int value;
    // ... other fields

    public Entry(Terrain terrain, int value, ...) { ... }
}

@ConfigurationProperties("section")
@ConstructorBinding
@Validated
class SectionProperties {
    private final List<Entry> entries;

    public SectionProperties(List<Entry> entries) {
        this.entries=  List.copyOf(entries);
    }

    // ... other fields, getters, etc
}

Это прекрасно работает, если YAML структурирован как последовательность объектов, подобная этой:

section:
  entries:
    - terrain: plains
      value: 1
    - terrain: forest
      value: 2

Однако было бы замечательно с точки зрения пользователя / автора этой конфигурации, если бы данные были организованы как «электронная таблица», поскольку тогда они могли бы видеть различные значения в контексте друг друга, а не большого списка. выше (там около десятка или около того записей). Примерно так:

section:
  entries:
    - [plains, 1]
    - [forest, 2]

Это допустимый YAML (насколько я могу судить), но привязка конфигурации завершается неудачно с ошибкой «unbound properties» для каждой записи в списке, т.е. она, кажется, распознает entries как последовательность YAML, но не может связать данные в блоке последовательности YAML (квадратные скобки) с Entry.

Кто-нибудь пытался сделать это или что-то подобное? Возможно ли это?

Извинения, если об этом уже говорилось в другом месте, я искал документацию SO и Spring, но не могу найти ничего, что охватывало бы этот конкретный c случай и действительно ли это возможно.

1 Ответ

0 голосов
/ 29 апреля 2020

Это должно быть возможно, если вы реализуете сопоставление самостоятельно:

@Component
@ConfigurationPropertiesBinding
public class EntryConverter implements Converter<List<String>, Entry> {
    @Autowired
    private ConversionService conversionService;

    @Override
    public Entry convert(List<String> from) {
        String[] data = from.split(",");
        return new Entry(data[0],
                conversionService.convert(data[1], Integer.class), ...);
    }
}

Я не уверен, сработает ли это нескалярные значения, вложенные в список. Я также не уверен, работает ли оно для List<Entry> , Попробуйте и доложите:).

...