1. Введение

В этом уроке мы покажем, как внедрять коллекции Java с помощью среды Spring.

Проще говоря, мы продемонстрируем примеры с интерфейсами коллекции List, Map, Set.

2. Список с помощью @Autowired

Давайте создадим пример bean-компонента:

Здесь мы объявили свойство nameList для хранения списка строковых значений.

public class CollectionsBean {

    @Autowired
    private List<String> nameList;

    public void printNameList() {
        System.out.println(nameList);
    }
}

В этом примере мы используем внедрение полей для nameList. Поэтому ставим аннотацию @Autowired.

Чтобы узнать больше о внедрении зависимостей или различных способах его реализации, ознакомьтесь с этим руководством.

После этого мы регистрируем CollectionsBean в классе настройки конфигурации:

Помимо регистрации CollectionsBean, мы также вводим новый список, явно инициализируя и возвращая его как отдельную конфигурацию @Bean.

@Configuration
public class CollectionConfig {

    @Bean
    public CollectionsBean getCollectionsBean() {
        return new CollectionsBean();
    }

    @Bean
    public List<String> nameList() {
        return Arrays.asList("John", "Adam", "Harry");
    }
}

Теперь мы можем проверить результаты:

Вывод метода printNameList():

ApplicationContext context = new AnnotationConfigApplicationContext(CollectionConfig.class);
CollectionsBean collectionsBean = context.getBean(
  CollectionsBean.class);
collectionsBean.printNameList();

3. Set With Constructor Injection

[John, Adam, Harry]

Чтобы настроить тот же пример с коллекцией Set , давайте изменим класс CollectionsBean:

На этот раз мы хотим использовать внедрение конструктора для инициализации свойства nameSet. Это требует также изменений в классе конфигурации:

public class CollectionsBean {

    private Set<String> nameSet;

    public CollectionsBean(Set<String> strings) {
        this.nameSet = strings;
    }

    public void printNameSet() {
        System.out.println(nameSet);
    }
}

4. Карта с внедрением сеттера

@Bean
public CollectionsBean getCollectionsBean() {
    return new CollectionsBean(new HashSet<>(Arrays.asList("John", "Adam", "Harry")));
}

Следуя той же логике, давайте добавим поле nameMap для демонстрации внедрения карты:

На этот раз у нас есть setter, чтобы использовать инъекцию зависимостей setter. Нам также необходимо добавить код инициализации карты в класс конфигурации:

public class CollectionsBean {

    private Map<Integer, String> nameMap;

    @Autowired
    public void setNameMap(Map<Integer, String> nameMap) {
        this.nameMap = nameMap;
    }

    public void printNameMap() {
        System.out.println(nameMap);
    }
}

Результаты после вызова метода printNameMap():

@Bean
public Map<Integer, String> nameMap(){
    Map<Integer, String>  nameMap = new HashMap<>();
    nameMap.put(1, "John");
    nameMap.put(2, "Adam");
    nameMap.put(3, "Harry");
    return nameMap;
}

5. Внедрение ссылок на компоненты

{1=John, 2=Adam, 3=Harry}

Давайте рассмотрим пример, в котором мы вводить ссылки на bean-компоненты как элементы коллекции.

Сначала создадим bean-компонент:

И добавим List of BaeldungBean в качестве свойства в класс CollectionsBean:

public class BaeldungBean {

    private String name;

    // constructor
}

Затем мы добавим фабричные методы конфигурации Java для каждого элемента BaeldungBean:

public class CollectionsBean {

    @Autowired(required = false)
    private List<BaeldungBean> beanList;

    public void printBeanList() {
        System.out.println(beanList);
    }
}

Контейнер Spring внедряет отдельные bean-компоненты типа BaeldungBean в одну коллекцию.

@Configuration
public class CollectionConfig {

    @Bean
    public BaeldungBean getElement() {
        return new BaeldungBean("John");
    }

    @Bean
    public BaeldungBean getAnotherElement() {
        return new BaeldungBean("Adam");
    }

    @Bean
    public BaeldungBean getOneMoreElement() {
        return new BaeldungBean("Harry");
    }

    // other factory methods
}

Чтобы проверить это, мы вызываем метод collectionsBean.printBeanList(). Вывод показывает имена bean-компонентов в виде элементов списка:

Теперь давайте рассмотрим сценарий, когда BaeldungBean отсутствует. Если в контексте приложения не зарегистрирован BaeldungBean, Spring выдаст исключение из-за отсутствия требуемой зависимости.

[John, Harry, Adam]

Мы можем использовать @Autowired(required = false), чтобы пометить зависимость как необязательную. Вместо создания исключения beanList не будет инициализирован, и его значение останется нулевым.

Если нам нужен пустой список вместо null, мы можем инициализировать beanList новым ArrayList:

5.1. Использование @Order для сортировки бинов

@Autowired(required = false)
private List<BaeldungBean> beanList = new ArrayList<>();

Мы можем указать порядок бинов при вставке в коллекцию.

Для этой цели мы используем аннотацию @Order и указываем индекс:

Контейнер Spring сначала введет bean-компонент с именем «Harry», так как он имеет наименьшее значение порядка.

@Configuration
public class CollectionConfig {

    @Bean
    @Order(2)
    public BaeldungBean getElement() {
        return new BaeldungBean("John");
    }

    @Bean
    @Order(3)
    public BaeldungBean getAnotherElement() {
        return new BaeldungBean("Adam");
    }

    @Bean
    @Order(1)
    public BaeldungBean getOneMoreElement() {
        return new BaeldungBean("Harry");
    }
}

Затем он внедрит бин «John» и, наконец, бин «Adam»:

Узнайте больше о @Order в этом руководстве.

[Harry, John, Adam]

5.2. Использование @Qualifier для выбора Bean-компонентов

Мы можем использовать @Qualifier для выбора bean-компонентов для внедрения в конкретную коллекцию, которая соответствует имени @Qualifier.

Вот как мы используем его для точки внедрения:

Затем мы помечаем тем же @Qualifier bean-компоненты, которые хотим внедрить в список:

@Autowired
@Qualifier("CollectionsBean")
private List<BaeldungBean> beanList;

В этом примере мы укажите, что компонент с именем «John» будет внедрен в список с именем «CollectionsBean». Результаты, которые мы тестируем здесь:

@Configuration
public class CollectionConfig {

    @Bean
    @Qualifier("CollectionsBean")
    public BaeldungBean getElement() {
        return new BaeldungBean("John");
    }

    @Bean
    public BaeldungBean getAnotherElement() {
        return new BaeldungBean("Adam");
    }

    @Bean
    public BaeldungBean getOneMoreElement() {
        return new BaeldungBean("Harry");
    }

    // other factory methods
}

Из вывода мы видим, что наша коллекция имеет только один элемент:

ApplicationContext context = new AnnotationConfigApplicationContext(CollectionConfig.class);
CollectionsBean collectionsBean = context.getBean(CollectionsBean.class);
collectionsBean.printBeanList();

6. Установка пустого списка в качестве значения по умолчанию

[John]

Мы можем установить значение по умолчанию значение для внедренного свойства List в виде пустого списка с помощью статического метода Collections.emptyList():

Если мы запустим это с ключом «names.list», не инициализированным через файл свойств:

public class CollectionsBean {

    @Value("${names.list:}#{T(java.util.Collections).emptyList()}")
    private List<String> nameListWithDefaultValue;
    
    public void printNameListWithDefaults() {
        System.out.println(nameListWithDefaultValue);
    }
}

~ ~~ На выходе мы получим пустой список:

collectionsBean.printNameListWithDefaults();

7. Резюме

[ ]

«С помощью этого руководства мы узнали, как внедрять различные типы коллекций Java с помощью среды Spring.

Мы также рассмотрели внедрение ссылочных типов и то, как их выбирать или упорядочивать внутри коллекции.

Как обычно, полный код доступен в проекте GitHub.

«