Sotirios Delimanolis opened SPR-15117 and commented
This issue follows the findings in this Stack Overflow question.
Consider the following
@Component
class TestControl {
@Autowired
public TestControl(BiMap<String, Integer> parameter) { }
}
@Configuration
public class Example {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(Example.class, TestControl.class);
}
@Bean
BiMap<String, Integer> someBiMap() {
return ImmutableBiMap.of("some key", someFoo());
}
@Bean
Integer someFoo() {
return 6;
}
}
The expect behavior is for the bean named someBiMap to be injected in the TestControl constructor.
Instead, we get a BeanInstantiationException
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.example.TestControl]: Illegal arguments for constructor; nested exception is java.lang.IllegalArgumentException: argument type mismatch
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:158)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:122)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:267)
... 13 more
Caused by: java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147)
... 15 more
We can work around this by qualifying the parameter name
public TestControl(@Qualifier("someBiMap") BiMap<String, Integer> parameter) {}
or using using field injection with @Resource and the appropriate name, assuming the field is non-final.
However, the documentation states
That said, as of 4.3, collection/map and array types can be matched through Spring’s @Autowired type matching algorithm as well, as long as the element type information is preserved in @Bean return type signatures or collection inheritance hierarchies.
which makes me think this is a bug. The resolution for a Map of bean names to beans seems to take precedence over the resolution by type.
Affects: 4.3.2
Issue Links:
Sotirios Delimanolis opened SPR-15117 and commented
This issue follows the findings in this Stack Overflow question.
Consider the following
The expect behavior is for the bean named
someBiMapto be injected in theTestControlconstructor.Instead, we get a
BeanInstantiationExceptionWe can work around this by qualifying the parameter name
or using using field injection with
@Resourceand the appropriate name, assuming the field is non-final.However, the documentation states
which makes me think this is a bug. The resolution for a
Mapof bean names to beans seems to take precedence over the resolution by type.Affects: 4.3.2
Issue Links: