当前位置: 首页 > 知识库问答 >
问题:

Spring自动布线在使用FactoryBean创建泛型类型的实例时无法连接泛型类型

苏嘉志
2023-03-14

我试图解析spring Version4.3.6中FactoryBean中的泛型类型。我使用FactoryBean创建bean,该bean用于创建任意数量的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);

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

关于如何解析FactoryBean中的泛型类型,而不依赖于bean名称(而是依赖于类型),有什么想法吗?

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

共有1个答案

桓信鸥
2023-03-14

我通过解析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

 类似资料:
  • 问题内容: 是否可以在Java中创建泛型类型的实例?我正在根据我所看到的答案进行思考no(由于类型擦除),但是如果有人能看到我所缺少的内容,我将很感兴趣: 编辑:事实证明,超级类型令牌可以用于解决我的问题,但是它需要很多基于反射的代码,如下面的一些答案所示。 问题答案: 你是对的。你做不到。但你可以将其更改为 但这有效。以工厂模式包装它会使它更具容忍性。

  • 问题内容: 我的问题是这样的: 为什么不能使用类Class的new T()和newInstance()实例化泛型? 问题答案: 您需要使用反射(),因为在编译时需要链接其构造函数的类是未知的。因此,编译器无法生成链接。

  • 问题内容: 我有这堂课 我正在尝试使用此方法在此类之外创建变量 这给了我这个错误 问题答案: 在实例化泛型时,应将其替换为相应的对象。 例如:

  • 编译时,此代码将产生以下+错误: 问题是访问中的类型T与列表中的T不相同。如何修复此编译问题?

  • 如何将Java7类型推断用于泛型实例创建功能?使用这种新样式有什么好处?