弹簧自动布线无法使用泛型类型,当使用FactoryBean创建泛型类型的实例时



我正在尝试在春季版本 4.3.6 中解析 FactoryBean 中的泛型类型。我使用FactoryBean创建bean,该FactoryBean用于创建任意数量的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;
}
}

我正在注册这些豆子如下,

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);
}
}

最后,我在AppConfig中导入CarClientRegistrar,

@Import({CarClientRegistrar.class})
public class ApplicationConfig {
}

并自动连接汽车客户端,

@RestController
@RequestMapping(value = "blah")
public class CallsController {
private CarClient<Ford> fb;
@Autowired
public CallsController(CarClient<Ford> fordBean){
this.fb = fordBean;
}
}

我得到以下异常,

通过构造函数参数 1 表示的未满足的依赖关系;嵌套异常是 org.springframework.beans.factory.NoUniqueBeanDefinitionException: 没有类型为 'com.empire.client.CarClient' 的限定 bean: 预期的单个匹配 bean,但找到 2: car1Impl,car2Impl

但是,如果我重命名,fordBean为car1Impl(这是必需的bean(,它可以工作

@Autowired
public CallsController(CarClient<Ford> car1Impl){
this.fb = fordBean;
}

关于如何在不依赖于 Bean 名称(但取决于类型(的情况下解析 FactoryBean 中的泛型类型的任何想法?

ResolvableType resolvableType = ResolvableType.forClassWithGenerics(CarClient.class, type);
return resolvableType.resolve(); 

似乎不起作用。

提前感谢!

我通过在CarClientRegistrar中解析类型并将其作为目标类型分配给BeanDefinition来解决此问题。

ResolvableType resolvableType = ResolvableType.forClassWithGenerics(AsyncClient.class, serviceInterface);
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
rootBeanDefinition.setTargetType(resolvableType);
rootBeanDefinition.setBeanClass(CarFactoryBean.class);
rootBeanDefinition.getPropertyValues().add("type", serviceInterface);
rootBeanDefinition.setDescription("desc");

而不是使用 GenericBeanDefinition

最新更新