Closed
Description
Simic Zhang opened SPR-15373 and commented
While I tries to inject List<Provider<Animal>> via below code, it throws error :
" No qualifying bean of type 'java.util.List<javax.inject.Provider<simic.test.spring.Animal>>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org
.springframework.beans.factory.annotation.Autowired(required=true)}"
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={Cat.class,Dog.class,PetShop.class})
public class SpringTest {
@Autowired
private PetShop shop;
@Test
public void testFoo() {
for(Provider<Animal> animalProvider : shop.animals){
System.out.println(animalProvider.get());
}
}
}
@Component
public class PetShop {
@Autowired
protected List<Provider<Animal>> animals;
}
@Component
public class Dog implements Animal {}
@Component
public class Cat implements Animal {}
public interface Animal {}
I tried to make a fix by adding below code to DefaultListableBeanFactory.resolveMultipleBeans()
else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric();
if (elementType == null) {
return null;
}
if (javaxInjectProviderClass == elementType) {
String[] candidateBeanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this,descriptor.getResolvableType().resolveGeneric(0,0), true, descriptor.isEager());
List<Provider<Object>> providers = new ArrayList<>();
for(String candidateBeanName : candidateBeanNames) {
providers.add(new Provider<Object>(){
@Override
public Object get() {
return getBean(candidateBeanName);
}});
}
return providers;
}
Affects: 4.3.7
Issue Links:
- Honor @Autowired(required=false) at parameter level, as an alternative to java.util.Optional [SPR-15268] #19833 Honor
@Autowired
(required=false) at parameter level, as an alternative to java.util.Optional