Весна - впрыскивание коллекций

Весна - инъекционные коллекции

1. Вступление

В этом уроке мы покажем, какinject Java collections using the Spring framework.

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

2. List с@Autowired

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

public class CollectionsBean {

    @Autowired
    private List nameList;

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

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

In this example, we use field injection for nameList. Therefore, we put the @Autowired annotation.

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

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

@Configuration
public class CollectionConfig {

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

    @Bean
    public List 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 с внедрением конструктора

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

public class CollectionsBean {

    private Set nameSet;

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

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

This time we want to use a constructor injection for initializing the nameSet property. Это требует также изменений в классе конфигурации:

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

4. Map с впрыском через сеттер

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

public class CollectionsBean {

    private Map nameMap;

    @Autowired
    public void setNameMap(Map nameMap) {
        this.nameMap = nameMap;
    }

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

На этот разwe have a setter method in order to use a setter dependency injection. Нам также необходимо добавить код инициализацииMap в класс конфигурации:

@Bean
public Map nameMap(){
    Map  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-компонент:

public class exampleBean {

    private String name;

    // constructor
}

И добавьтеList изexampleBean в качестве свойства в классCollectionsBean :

public class CollectionsBean {

    @Autowired(required = false)
    private List beanList;

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

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

@Configuration
public class CollectionConfig {

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

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

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

    // other factory methods
}

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

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

[John, Harry, Adam]

Теперьlet’s consider a scenario when there is not a exampleBean. Если в контексте приложения не зарегистрированexampleBean, Spring выдаст исключение, поскольку требуемая зависимость отсутствует.

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

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

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

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

We can specify the order of the beans while injecting into the collection.

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

@Configuration
public class CollectionConfig {

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

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

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

Spring container first will inject the bean with the name “Harry”, так как он имеет наименьшее значение порядка.

Затем он внедрит“John”, и, наконец, bean-компонент“Adam”:

[Harry, John, Adam]

Узнайте больше о@Order в этомguide.

5.2. Использование@Qualifier для выбора фасоли

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

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

@Autowired
@Qualifier("CollectionsBean")
private List beanList;

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

@Configuration
public class CollectionConfig {

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

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

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

    // other factory methods
}

В этом примере мы указываем, что компонент с именем“John” will будет внедрен вList с именем“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 nameListWithDefaultValue;

    public void printNameListWithDefaults() {
        System.out.println(nameListWithDefaultValue);
    }
}

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

collectionsBean.printNameListWithDefaults();

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

[ ]

7. Резюме

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

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

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