2017-08-23 6 views
2

Springバージョン4.3.6のFactoryBeanでジェネリック型を解決しようとしています。 CarClientのインスタンスをいくつでも作成するために使用されるFactoryBeanを使用してBeanを作成します。次のように私はこれらのBeanを登録していますFactoryBeanを使用してジェネリック型のインスタンスを作成するときにSpring自動配線がジェネリック型にできない

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 { 

} 

とCarClientをオートワイヤリング

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

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

私はe次の例外を除いて、

コンストラクタパラメータ1で表される満足しない依存関係。タイプのいかなる予選Beanのcom.empire.client.CarClient "利用可能:シングルマッチ豆期待されるが、2を見つけました:ネストされた例外はorg.springframework.beans.factory.NoUniqueBeanDefinitionExceptionではありませんcar1Impl、car2Impl

しかし、私は名前を変更する場合には、 (必要な豆です)car1ImplにfordBean、それはBean名(ただしタイプの)に依存せず、FactoryBeanのでジェネリック型を解決する方法について

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

任意のアイデアを作品?

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

は動作していないようです。

ありがとうございます!

+0

を使用して、私はこの記事では、それについての有用な情報があると思います。https://stackoverflow.com/questions/22603291/how-to-autowire-bean-of-generic春のタイプ –

答えて

1

私は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

関連する問題