I have a bean Item<T>
which is required to be autowired in a @Configuration
class.
@Configuration public class AppConfig { @Bean public Item<String> stringItem() { return new StringItem(); } @Bean public Item<Integer> integerItem() { return new IntegerItem(); } }
But when I try to @Autowire Item<String>
, I get following exception.
"No qualifying bean of type [Item] is defined: expected single matching bean but found 2: stringItem, integerItem"
How should I Autowire generic type Item<T>
in Spring?
This mode specifies autowiring by property type. Spring container looks at the beans on which autowire attribute is set to byType in the XML configuration file. It then tries to match and wire a property if its type matches with exactly one of the beans name in the configuration file.
@Bean is just for the metadata definition to create the bean(equivalent to tag). @Autowired is to inject the dependancy into a bean(equivalent to ref XML tag/attribute).
The main difference is is that @Autowired is a spring annotation whereas @Resource is specified by the JSR-250. So the latter is part of normal java where as @Autowired is only available by spring.
< T > is a conventional letter that stands for "Type", and it refers to the concept of Generics in Java. You can use any letter, but you'll see that 'T' is widely preferred. WHAT DOES GENERIC MEAN? Generic is a way to parameterize a class, method, or interface.
Simple solution is to upgrade to Spring 4.0 as it will automatically consider generics as a form of @Qualifier
, as below:
@Autowired private Item<String> strItem; // Injects the stringItem bean @Autowired private Item<Integer> intItem; // Injects the integerItem bean
Infact, you can even autowire nested generics when injecting into a list, as below:
// Inject all Item beans as long as they have an <Integer> generic // Item<String> beans will not appear in this list @Autowired private List<Item<Integer>> intItems;
How this Works?
The new ResolvableType
class provides the logic of actually working with generic types. You can use it yourself to easily navigate and resolve type information. Most methods on ResolvableType
will themselves return a ResolvableType
, for example:
// Assuming 'field' refers to 'intItems' above ResolvableType t1 = ResolvableType.forField(field); // List<Item<Integer>> ResolvableType t2 = t1.getGeneric(); // Item<Integer> ResolvableType t3 = t2.getGeneric(); // Integer Class<?> c = t3.resolve(); // Integer.class // or more succinctly Class<?> c = ResolvableType.forField(field).resolveGeneric(0, 0);
Check out the Examples & Tutorials at below links.
Hope this helps you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With