I am trying to resolve generic types in a FactoryBean in spring version 4.3.6. I create the beans using a FactoryBean which is used to create any number of instances of CarClient.
public class CarFactoryBean<T> implements FactoryBean<CarClient<T>>{
@Autowired
CarClientCreationHelper cch;
private Class<T> type;
@Overrides
public CarClient<T> getObject() throws Exception {
return cch.provideCar(type);
}
@Override
public Class<?> getObjectType() {
ResolvableType resolvableType = ResolvableType.forClassWithGenerics(CarClient.class, type);
return resolvableType.resolve();
}
@Override
public boolean isSingleton() {
return true;
}
public void setType(Class<T> type) {
this.type = type;
}
}
I am registering these beans as follows,
public class CarClientRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {
private MyBeanNameGenerator bng;
public CarClientRegistrar(){
this.bng = new MyBeanNameGenerator();
}
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//logic to obtain serviceInterface, working correctly
AbstractBeanDefinition definition = BeanDefinitionBuilder.genericBeanDefinition(CarFactoryBean.class)
.addPropertyValue("type", serviceInterface)
.getBeanDefinition();
definition.setDescription("desc");
final String beanName = bng.generateBeanName(definition, registry);
BeanDefinitionReaderUtils.registerBeanDefinition(new BeanDefinitionHolder(definition, beanName,
new String[]{beanName.substring(0, beanName.lastIndexOf("/"))}), registry);
}
}
Finally, i am importing the CarClientRegistrar in the AppConfig,
@Import({CarClientRegistrar.class})
public class ApplicationConfig {
}
and autowiring a CarClient,
@RestController
@RequestMapping(value = "blah")
public class CallsController {
private CarClient<Ford> fb;
@Autowired
public CallsController(CarClient<Ford> fordBean){
this.fb = fordBean;
}
}
I get the following exception,
Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.empire.client.CarClient' available: expected single matching bean but found 2: car1Impl,car2Impl
However, if i rename, fordBean to car1Impl (which is the required bean), it works
@Autowired
public CallsController(CarClient<Ford> car1Impl){
this.fb = fordBean;
}
Any ideas on how to resolve the generic type in the FactoryBean, without depending on bean name (but on type)?
ResolvableType resolvableType = ResolvableType.forClassWithGenerics(CarClient.class, type);
return resolvableType.resolve();
doesn't seem to work.
Thanks in advance!