Spring – Injecting Collections

1. Introduction

In this tutorial, we’re going to show how to inject Java collections using the Spring framework.

Simply put, we’ll demonstrate examples with the List, Map, Set collection interfaces.

2. List With @Autowired

Let’s create an example bean:

public class CollectionsBean {

    @Autowired
    private List<String> nameList;

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

Here, we declared the nameList property to hold a List of String values.

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

To learn more about the dependency injection or different ways to implement it, check out this guide.

After, we register the CollectionsBean in the configuration setup class:

@Configuration
public class CollectionConfig {

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

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

Besides registering the CollectionsBean, we also inject a new list by explicitly initializing and returning it as a separate @Bean configuration.

Now, we can test the results:

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

The output of printNameList() method:

[John, Adam, Harry]

3. Set With Constructor Injection

To set up the same example with the Set collection, let’s modify the CollectionsBean class:

public class CollectionsBean {

    private Set<String> nameSet;

    public CollectionsBean(Set<String> 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. This requires also changes in configuration class:

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

4. Map With Setter Injection

Following the same logic, let’s add the nameMap field to demonstrate the map injection:

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);
    }
}

This time we have a setter method in order to use a setter dependency injection. We also need to add the Map initializing code in configuration class:

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

The results after invoking the printNameMap() method:

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

5. Injecting Bean References

Let’s look at an example where we inject bean references as elements of the collection.

First, let’s create the bean:

public class VietMXBean {

    private String name;

    // constructor
}

And add a List of VietMXBean as a property to the CollectionsBean class:

public class CollectionsBean {

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

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

Next, we add the Java configuration factory methods for each VietMXBean element:

@Configuration
public class CollectionConfig {

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

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

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

    // other factory methods
}

The Spring container injects the individual beans of the VietMXBean type into one collection.

To test this, we invoke the collectionsBean.printBeanList() method. The output shows the bean names as list elements:

[John, Harry, Adam]

Now, let’s consider a scenario when there is not a VietMXBean. If there isn’t a VietMXBean registered in the application context, Spring will throw an exception because the required dependency is missing.

We can use @Autowired(required = false) to mark the dependency as optional. Instead of throwing an exception, the beanList won’t be initialized and its value will stay null.

If we need an empty list instead of null, we can initialize beanList with a new ArrayList:

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

5.1. Using @Order to Sort Beans

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

For that purpose, we use the @Order annotation and specify the index:

@Configuration
public class CollectionConfig {

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

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

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

Spring container first will inject the bean with the name “Harry”, as it has the lowest order value.

It will then inject the “John”, and finally, the “Adam” bean:

[Harry, John, Adam]

Learn more about @Order in this guide.

5.2. Using @Qualifier to Select Beans

We can use the @Qualifier to select the beans to be injected into the specific collection that matches the @Qualifier name.

Here’s how we use it for the injection point:

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

Then, we mark with the same @Qualifier the beans that we want to inject into the List:

@Configuration
public class CollectionConfig {

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

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

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

    // other factory methods
}

In this example, we specify that the bean with the name “John” will be injected into the List named “CollectionsBean”. The results we test here:

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

From the output, we see that our collection has only one element:

[John]

6. Setting an Empty List as a Default Value

We can set the default value for an injected List property as an empty list by using the Collections.emptyList() static method:

public class CollectionsBean {

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

If we run this with the “names.list” key not initialized via properties file:

collectionsBean.printNameListWithDefaults();

We’ll get an empty list as output:

[ ]

7. Summary

With this guide, we learned how to inject different types of Java collections using the Spring framework.

We also examined injection with reference types and how to select or order them inside of the collection.

As usual, the complete code is available in the GitHub project.

Related posts:

Java Program to Find Location of a Point Placed in Three Dimensions Using K-D Trees
Finding Max/Min of a List or Collection
Java Program to Check if a Matrix is Invertible
Spring Boot With H2 Database
Một số tính năng mới về xử lý ngoại lệ trong Java 7
Java Program to Implement Treap
HashMap trong Java hoạt động như thế nào?
Reactive WebSockets with Spring 5
Java Program to Implement Ternary Heap
Java Program to Find the Vertex Connectivity of a Graph
How to Manually Authenticate User with Spring Security
Netflix Archaius with Various Database Configurations
The Guide to RestTemplate
Derived Query Methods in Spring Data JPA Repositories
wait() and notify() Methods in Java
What is Thread-Safety and How to Achieve it?
Hướng dẫn sử dụng Lớp FilePermission trong java
Java Program to Implement Dijkstra’s Algorithm using Set
How to Use if/else Logic in Java 8 Streams
Inheritance and Composition (Is-a vs Has-a relationship) in Java
Introduction to Java Serialization
Chuyển đổi từ HashMap sang ArrayList
Custom Thread Pools In Java 8 Parallel Streams
Java Program to Implement Sieve Of Eratosthenes
Guide to Java Instrumentation
Java Program to Implement Flood Fill Algorithm
Java Program to Implement Sorting of Less than 100 Numbers in O(n) Complexity
Java Program to Generate All Possible Subsets with Exactly k Elements in Each Subset
Java Program to implement Circular Buffer
Guide to Spring Cloud Kubernetes
Spring Security Registration – Resend Verification Email
Using Spring @ResponseStatus to Set HTTP Status Code