1. Введение
В этом руководстве мы собираемся показать, как внедрять коллекции Java
с помощью среды Spring .
Проще говоря, мы продемонстрируем примеры с интерфейсами коллекции List, Map, Set .
2. Список
с @Autowired
Давайте создадим пример bean-компонента:
public class CollectionsBean {
@Autowired
private List<String> nameList;
public void printNameList() {
System.out.println(nameList);
}
}
Здесь мы объявили свойство nameList
для хранения списка
строковых
значений .
В этом примере мы используем внедрение полей для nameList
. Поэтому ставим аннотацию @Autowired
.
Чтобы узнать больше о внедрении зависимостей или различных способах его реализации, ознакомьтесь с этим руководством .
После этого мы регистрируем CollectionsBean
в классе настройки конфигурации:
@Configuration
public class CollectionConfig {
@Bean
public CollectionsBean getCollectionsBean() {
return new CollectionsBean();
}
@Bean
public List<String> nameList() {
return Arrays.asList("John", "Adam", "Harry");
}
}
Помимо регистрации CollectionsBean
, мы также вводим новый список, явно инициализируя и возвращая его как отдельную конфигурацию @Bean
.
Теперь мы можем проверить результаты:
ApplicationContext context = new AnnotationConfigApplicationContext(CollectionConfig.class);
CollectionsBean collectionsBean = context.getBean(
CollectionsBean.class);
collectionsBean.printNameList();
Вывод метода printNameList():
[John, Adam, Harry]
3. Установить
с внедрением конструктора
Чтобы настроить тот же пример с коллекцией Set
, давайте изменим класс CollectionsBean :
public class CollectionsBean {
private Set<String> nameSet;
public CollectionsBean(Set<String> strings) {
this.nameSet = strings;
}
public void printNameSet() {
System.out.println(nameSet);
}
}
На этот раз мы хотим использовать внедрение конструктора для инициализации свойства nameSet
. Это требует также изменений в классе конфигурации:
@Bean
public CollectionsBean getCollectionsBean() {
return new CollectionsBean(new HashSet<>(Arrays.asList("John", "Adam", "Harry")));
}
4. Карта
с внедрением сеттера
Следуя той же логике, давайте добавим поле nameMap
для демонстрации внедрения карты:
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);
}
}
На этот раз у нас есть метод setter, чтобы использовать инъекцию зависимостей setter . Нам также нужно добавить код инициализации карты
в класс конфигурации:
@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;
}
Результаты после вызова метода printNameMap()
:
{1=John, 2=Adam, 3=Harry}
5. Внедрение ссылок на компоненты
Давайте рассмотрим пример, в котором мы вводим ссылки на bean-компоненты как элементы коллекции.
Во-первых, давайте создадим bean-компонент:
public class ForEachBean {
private String name;
// constructor
}
И добавьте список
ForEachBean
в качестве свойства в класс CollectionsBean :
public class CollectionsBean {
@Autowired(required = false)
private List<ForEachBean> beanList;
public void printBeanList() {
System.out.println(beanList);
}
}
Затем мы добавляем фабричные методы конфигурации Java для каждого элемента ForEachBean
:
@Configuration
public class CollectionConfig {
@Bean
public ForEachBean getElement() {
return new ForEachBean("John");
}
@Bean
public ForEachBean getAnotherElement() {
return new ForEachBean("Adam");
}
@Bean
public ForEachBean getOneMoreElement() {
return new ForEachBean("Harry");
}
// other factory methods
}
Контейнер Spring внедряет отдельные компоненты типа ForEachBean
в одну коллекцию.
Чтобы проверить это, мы вызываем метод collectionsBean.printBeanList()
. Вывод показывает имена bean-компонентов в виде элементов списка:
[John, Harry, Adam]
Теперь давайте рассмотрим сценарий, когда ForEachBean отсутствует
. Если в контексте приложения не зарегистрирован ForEachBean
, Spring выдаст исключение из-за отсутствия требуемой зависимости.
Мы можем использовать @Autowired(required = false)
, чтобы пометить зависимость как необязательную. Вместо создания исключения beanList
не будет инициализирован, и его значение останется нулевым
.
Если нам нужен пустой список вместо null,
мы можем инициализировать beanList
новым ArrayList:
@Autowired(required = false)
private List<ForEachBean> beanList = new ArrayList<>();
5.1. Использование @Order
для сортировки компонентов
Мы можем указать порядок bean-компонентов при внедрении в коллекцию .
Для этого используем аннотацию @Order
и указываем индекс:
@Configuration
public class CollectionConfig {
@Bean
@Order(2)
public ForEachBean getElement() {
return new ForEachBean("John");
}
@Bean
@Order(3)
public ForEachBean getAnotherElement() {
return new ForEachBean("Adam");
}
@Bean
@Order(1)
public ForEachBean getOneMoreElement() {
return new ForEachBean("Harry");
}
}
Контейнер Spring сначала введет bean-компонент с именем «Harry»
, так как он имеет наименьшее значение порядка.
Затем он внедрит бин «John»
и, наконец, бин «Adam»
:
[Harry, John, Adam]
Узнайте больше о @Order
в этом руководстве .
5.2. Использование @Qualifier
для выбора компонентов
Мы можем использовать @Qualifier
, чтобы выбрать bean-компоненты для внедрения в конкретную коллекцию, которая соответствует имени @Qualifier
.
Вот как мы используем его для точки впрыска:
@Autowired
@Qualifier("CollectionsBean")
private List<ForEachBean> beanList;
Затем мы помечаем тем же @Qualifier
bean-компоненты, которые мы хотим внедрить в список
:
@Configuration
public class CollectionConfig {
@Bean
@Qualifier("CollectionsBean")
public ForEachBean getElement() {
return new ForEachBean("John");
}
@Bean
public ForEachBean getAnotherElement() {
return new ForEachBean("Adam");
}
@Bean
public ForEachBean getOneMoreElement() {
return new ForEachBean("Harry");
}
// other factory methods
}
В этом примере мы указываем, что bean-компонент с именем «John»
будет внедрен в список
с именем «CollectionsBean»
. Результаты, которые мы тестируем здесь:
ApplicationContext context = new AnnotationConfigApplicationContext(CollectionConfig.class);
CollectionsBean collectionsBean = context.getBean(CollectionsBean.class);
collectionsBean.printBeanList();
Из вывода мы видим, что наша коллекция имеет только один элемент:
[John]
6. Установка пустого списка в качестве значения по умолчанию
Мы можем установить значение по умолчанию для введенного свойства List как пустой список, используя статический метод Collections.emptyList() :
public class CollectionsBean {
@Value("${names.list:}#{T(java.util.Collections).emptyList()}")
private List<String> nameListWithDefaultValue;
public void printNameListWithDefaults() {
System.out.println(nameListWithDefaultValue);
}
}
Если мы запустим это с ключом «names.list», не инициализированным через файл свойств:
collectionsBean.printNameListWithDefaults();
На выходе мы получим пустой список:
[ ]
7. Резюме
С помощью этого руководства мы узнали, как внедрять различные типы коллекций Java с помощью среды Spring.
Мы также рассмотрели внедрение ссылочных типов и то, как их выбирать или упорядочивать внутри коллекции.
Как обычно, полный код доступен в проекте GitHub .