Spring Autowiring of Generic Types

1. Overview

In this tutorial, we’ll see how to inject Spring beans by generic parameters.

2. Autowiring Generics in Spring 3.2.

Spring supports injection of generic types since version 3.2.

Suppose we have an abstract class called Vehicle and a concrete sub-class of it called Car:

public abstract class Vehicle {
    private String name;
    private String manufacturer;
 
    // ... getters, setters etc
}
public class Car extends Vehicle {
    private String engineType;
 
    // ... getters, setters etc
}

Suppose we want to inject a list of objects of type Vehicle into some handler class:

@Autowired
private List<Vehicle> vehicles;

Spring will autowire all the Vehicle instance beans into this list. It doesn’t matter how we instantiate these beans through Java or XML configuration.

We may also use qualifiers to get only specific beans of the Vehicle type. Then we create @CarQualifier and annotate it with @Qualifier:

@Target({
  ElementType.FIELD, 
  ElementType.METHOD,
  ElementType.TYPE, 
  ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface CarQualifier {
}

Now we may use this annotation on our list to get only some specific Vehicles:

@Autowired
@CarQualifier
private List<Vehicle> vehicles;

In this case, we may create several Vehicle beans but Spring will only inject those with @CarQualifier into the list above:

public class CustomConfiguration {
    @Bean
    @CarQualifier
    public Car getMercedes() {
        return new Car("E280", "Mercedes", "Diesel");
    }
}

3. Autowiring Generics in Spring 4.0.

Suppose we have another Vehicle sub-class called Motorcycle:

public class Motorcycle extends Vehicle {
    private boolean twoWheeler;
    //... getters, setters etc
}

Now, if we want to inject only the Car beans into our list but no Motorcycle ones, we can do this by using the specific sub-class as a type parameter:

@Autowired
private List<Car> vehicles;

Spring lets us use a generic type as a qualifier without the need for an explicit annotation since version 4.0.

Prior to Spring 4.0, the code above wouldn’t work with beans of multiple subclasses of Vehicle. Without explicit qualifiers, we would receive a NonUniqueBeanDefinitionException.

4. ResolvableType

The generics autowiring feature works with the help of ResolvableType class behind the scenes.

It was introduced in Spring 4.0 to encapsulate Java Type and handle access to supertypes, interfaces, generic parameters and finally resolve to a Class:

ResolvableType vehiclesType = ResolvableType.forField(getClass().getDeclaredField("vehicles"));
System.out.println(vehiclesType);

ResolvableType type = vehiclesType.getGeneric();
System.out.println(type);

Class<?> aClass = type.resolve();
System.out.println(aClass);

The output of the above code would show the corresponding simple and generic types:

java.util.List<com.example.model.Vehicle>
com.example.model.Vehicle
class com.example.model.Vehicle

5. Conclusion

Injection of generic types is a powerful feature, which saves the developer the effort of assigning explicit qualifiers, making code cleaner and much more understandable.

As always the code can be found over on GitHub.

Related posts:

A Guide to the Java ExecutorService
Arrays.asList vs new ArrayList(Arrays.asList())
Spring Boot - Batch Service
Send an email with an attachment
Refactoring Design Pattern với tính năng mới trong Java 8
Java Program to Encode a Message Using Playfair Cipher
Các kiểu dữ liệu trong java
Spring Data MongoDB – Indexes, Annotations and Converters
Hướng dẫn Java Design Pattern – Observer
Java Program to Implement Triply Linked List
Phương thức tham chiếu trong Java 8 – Method References
Java Program to Implement Slicker Algorithm that avoids Triangulation to Find Area of a Polygon
Java Program to Implement Hash Tables Chaining with List Heads
Java Program to Generate All Possible Subsets with Exactly k Elements in Each Subset
Java Program to Implement Tarjan Algorithm
Java Program to Implement Queue using Linked List
Hướng dẫn Java Design Pattern – Facade
Tránh lỗi ConcurrentModificationException trong Java như thế nào?
Java Program to Implement HashMap API
Introduction to Java Serialization
Java Timer
Java Program to Implement Queue using Two Stacks
Java Program to Perform Matrix Multiplication
Giới thiệu Google Guice – Injection, Scope
Apache Commons Collections MapUtils
Collect a Java Stream to an Immutable Collection
Java List UnsupportedOperationException
Java Program to implement Bit Matrix
Display Auto-Configuration Report in Spring Boot
Java Program to Implement the linear congruential generator for Pseudo Random Number Generation
Call Methods at Runtime Using Java Reflection
Java Program to Perform Inorder Non-Recursive Traversal of a Given Binary Tree