Reputation: 861
The following issue was encountered while upgrading Spring 3.2 -> 4.1
There is a Metadata
hierarchy, like: AMetadata extends Metadata
,
BMetadata extends Metadata
etc.
There is a Processor
hierarchy, like:
abstract Processor<M extends Metadata>
,
AProcessor extends Processor<AMetadata>
,
BProcessor extends Processor<BMetadata>
etc
There is a service containing an injected List
of processors, like this:
@Inject
private List<Processor<Metadata>> processors;
While this worked perfectly in Spring 3.2, with Spring 4.1.0 (and 4.0 as well) it fails to inject list members. Going into debug, it was discovered that:
Processor<Metadata>.isAssignableFrom(BProcessor) == false
and this causes Processor beans not to be matched as eligible candidates for injection.
A possible hack-looking solution is to declare Processors as follows:
BProcessor<Metadata> extends Processor<BMetadata>
- that works, but looks a bit weird. Another option is to use List<Processor<? extends Metadata>>
, but this requires some code changes elsewhere to be compilable and causes a lot of type-safety-check warnings in classes which relied on generics.
So the question is, how to handle this case properly? Did anyone encountered something similar?
Upvotes: 0
Views: 285
Reputation: 5813
Also see video here Spring Framework on Java 8 https://www.youtube.com/watch?v=-_aWK8T_YMI that explains this. Generic type information was ingored till 4.0 Spring release. Now, they are taking into account.
Upvotes: 0
Reputation: 24561
Autowiring based on generics was one of the new features in Spring4. AFAIK they were ignored in previous versions. More info here: https://spring.io/blog/2013/12/03/spring-framework-4-0-and-java-generics
So I can't think of any other solution than you already pointed out: List<Processor<? extends Metadata>>
.
Upvotes: 1