Spring - Injecting Collections

Printemps - Collections injectées

1. introduction

Dans ce tutoriel, nous allons montrer commentinject Java collections using the Spring framework.

En termes simples, nous allons montrer des exemples avec les interfaces de collecteList, Map, Set.

2. List avec@Autowired

Créons un exemple de bean:

public class CollectionsBean {

    @Autowired
    private List nameList;

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

Ici, nous avons déclaré que la propriéténameList contenait unList de valeursString.

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

Pour en savoir plus sur l'injection de dépendances ou sur les différentes façons de l'implémenter, consultez ceguide.

Après, nous enregistrons leCollectionsBean in la classe de configuration de configuration:

@Configuration
public class CollectionConfig {

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

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

En plus d'enregistrer lesCollectionsBean, nous injectons également une nouvelle liste en l'initialisant explicitement et en la renvoyant comme une configuration@Bean distincte.

Maintenant, nous pouvons tester les résultats:

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

La sortie de la méthode printNameList ():

[John, Adam, Harry]

3. Set avec injection de constructeur

Pour configurer le même exemple avec la collectionSet, modifions la classeCollectionsBean :

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. Cela nécessite également des changements dans la classe de configuration:

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

4. Map avec injection de poseur

En suivant la même logique, ajoutons le champ nameMap pour illustrer l'injection de carte:

public class CollectionsBean {

    private Map nameMap;

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

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

Cette foiswe have a setter method in order to use a setter dependency injection. Nous devons également ajouter le code d'initialisationMap dans la classe de configuration:

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

Les résultats après avoir appelé la méthodeprintNameMap():

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

5. Injection de références de bean

Prenons un exemple où nous injectons des références de bean en tant qu'éléments de la collection.

Commençons par créer le bean:

public class exampleBean {

    private String name;

    // constructor
}

Et ajoutez unList deexampleBean en tant que propriété à la classeCollectionsBean :

public class CollectionsBean {

    @Autowired(required = false)
    private List beanList;

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

Ensuite, nous ajoutons les méthodes de fabrique de configuration Java pour chaque élémentexampleBean:

@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
}

Le conteneur Spring injecte les beans individuels du typeexampleBean dans une collection.

Pour tester cela, nous invoquons la méthodecollectionsBean.printBeanList(). La sortie affiche les noms de beans sous forme d'éléments de liste:

[John, Harry, Adam]

Maintenant,let’s consider a scenario when there is not a exampleBean. S'il n'y a pas deexampleBean enregistré dans le contexte de l'application, Spring lèvera une exception car la dépendance requise est manquante.

Nous pouvons utiliser@Autowired(required = false) pour marquer la dépendance comme facultative. Au lieu de lancer une exception, lesbeanList ne seront pas initialisés et sa valeur resteranull.

Si nous avons besoin d'une liste vide au lieu denull,, nous pouvons initialiserbeanList avec un nouveauArrayList:

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

5.1. Utilisation de@Order pour trier les haricots

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

Pour cela, nous utilisons l'annotation@Order et spécifions l'index:

@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”, car il a la valeur d'ordre le plus bas.

Il injectera ensuite les“John”, et enfin, le bean“Adam”:

[Harry, John, Adam]

En savoir plus sur@Order dans ceguide.

5.2. Utilisation de@Qualifier pour sélectionner des haricots

Nous pouvons utiliser les@Qualifier pour sélectionner les beans à injecter dans la collection spécifique qui correspond au nom de@Qualifier.

Voici comment nous l’utilisons pour le point d’injection:

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

Ensuite, nous marquons avec les mêmes@Qualifier les beans que nous voulons injecter dans lesList:

@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
}

Dans cet exemple, nous spécifions que le bean avec le nom“John” will sera injecté dans lesList nommés“CollectionsBean”. Les résultats que nous testons ici:

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

À la sortie, nous voyons que notre collection ne comporte qu'un seul élément:

[John]

6. Définition d'une liste vide comme valeur par défaut

Nous pouvons définir la valeur par défaut d'une propriété List injectée sous forme de liste vide en utilisant la méthode statique deCollections.emptyList():

public class CollectionsBean {

    @Value("${names.list:}#{T(java.util.Collections).emptyList()}")
    private List nameListWithDefaultValue;

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

Si nous exécutons ceci avec la clé “names.list” non initialisée via le fichier de propriétés:

collectionsBean.printNameListWithDefaults();

Nous obtiendrons une liste vide en sortie:

[ ]

7. Sommaire

Avec ce guide, nous avons appris à injecter différents types de collections Java à l’aide du framework Spring.

Nous avons également examiné l’injection avec des types de référence et la manière de les sélectionner ou de les commander à l’intérieur de la collection.

Comme d'habitude, le code complet est disponible dans lesGitHub project.