Spring - Injeção de coleções

Spring - Injeção de coleções

1. Introdução

Neste tutorial, vamos mostrar comoinject Java collections using the Spring framework.

Simplificando, vamos demonstrar exemplos com as interfaces de coleçãoList, Map, Set.

2. List com@Autowired

Vamos criar um exemplo de bean:

public class CollectionsBean {

    @Autowired
    private List nameList;

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

Aqui, declaramos que a propriedadenameList contém umList dos valoresString.

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

Para saber mais sobre a injeção de dependência ou diferentes maneiras de implementá-la, verifique esteguide.

Depois, registramos oCollectionsBean em a classe de configuração:

@Configuration
public class CollectionConfig {

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

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

Além de registrarCollectionsBean, também injetamos uma nova lista inicializando explicitamente e retornando-a como uma configuração@Bean separada.

Agora, podemos testar os resultados:

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

A saída do método printNameList ():

[John, Adam, Harry]

3. Set com injeção de construtor

Para configurar o mesmo exemplo com a coleçãoSet, vamos modificar o sclassCollectionsBean :

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. Isso também requer alterações na classe de configuração:

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

4. Map com injeção de setter

Seguindo a mesma lógica, vamos adicionar o campo nameMap para demonstrar a injeção do mapa:

public class CollectionsBean {

    private Map nameMap;

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

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

Desta vez,we have a setter method in order to use a setter dependency injection. Também precisamos adicionar o código de inicializaçãoMap na classe de configuração:

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

Os resultados após invocar o métodoprintNameMap():

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

5. Injetando referências de bean

Vejamos um exemplo em que injetamos referências de bean como elementos da coleção.

Primeiro, vamos criar o bean:

public class exampleBean {

    private String name;

    // constructor
}

E adicione umList deexampleBean como uma propriedade à classeCollectionsBean :

public class CollectionsBean {

    @Autowired(required = false)
    private List beanList;

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

Em seguida, adicionamos os métodos de fábrica de configuração Java para cada elementoexampleBean:

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

O contêiner Spring injeta os beans individuais do tipoexampleBean em uma coleção.

Para testar isso, invocamos o métodocollectionsBean.printBeanList(). A saída mostra os nomes dos beans como elementos da lista:

[John, Harry, Adam]

Agora,let’s consider a scenario when there is not a exampleBean. Se não houver umexampleBean registrado no contexto do aplicativo, o Spring lançará uma exceção porque a dependência necessária está ausente.

Podemos usar@Autowired(required = false) para marcar a dependência como opcional. Em vez de lançar uma exceção, obeanList não será inicializado e seu valor permaneceránull.

Se precisarmos de uma lista vazia em vez denull,, podemos inicializarbeanList com um novoArrayList:

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

5.1. Usando@Order para classificar os feijões

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

Para isso, usamos a anotação@Order e especificamos o índice:

@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”, pois possui o menor valor de pedido.

Em seguida, ele injetará o“John”,e, finalmente, o bean“Adam”:

[Harry, John, Adam]

Saiba mais sobre@Order nesteguide.

5.2. Usando@Qualifier para selecionar feijão

Podemos usar@Qualifier para selecionar os beans a serem injetados na coleção específica que corresponde ao nome@Qualifier.

Aqui está como o usamos para o ponto de injeção:

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

Em seguida, marcamos com o mesmo@Qualifier os grãos que queremos injetar noList:

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

Neste exemplo, especificamos que o bean com o nome“John” will seja injetado emList denominado“CollectionsBean”. Os resultados que testamos aqui:

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

A partir da saída, vemos que nossa coleção tem apenas um elemento:

[John]

6. Definir uma lista vazia como valor padrão

Podemos definir o valor padrão para uma propriedade List injetada como uma lista vazia usando o método estáticoCollections.emptyList():

public class CollectionsBean {

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

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

Se executarmos isso com a chave "names.list" não inicializada via arquivo de propriedades:

collectionsBean.printNameListWithDefaults();

Obteremos uma lista vazia como saída:

[ ]

7. Sumário

Com este guia, aprendemos como injetar diferentes tipos de coleções Java usando a estrutura Spring.

Também examinamos a injeção com tipos de referência e como selecioná-los ou solicitá-los dentro da coleção.

Como de costume, o código completo está disponível emGitHub project.