如何在Spring中自动assemblygenerics<T>的bean?

我有一个需要在@Configuration类中自动assembly的bean Item<T>

 @Configuration public class AppConfig { @Bean public Item<String> stringItem() { return new StringItem(); } @Bean public Item<Integer> integerItem() { return new IntegerItem(); } } 

但是当我尝试@Autowire Item<String> ,我得到以下exception。

 "No qualifying bean of type [Item] is defined: expected single matching bean but found 2: stringItem, integerItem" 

我应该怎么AutowiregenericstypesItem<T>在spring?

简单的解决scheme是升级到Spring 4.0,因为它会自动将generics视为@Qualifier一种forms,如下所示:

 @Autowired private Item<String> strItem; // Injects the stringItem bean @Autowired private Item<Integer> intItem; // Injects the integerItem bean 

事实上,你甚至可以在注入列表时自动装入嵌套的generics,如下所示:

 // Inject all Item beans as long as they have an <Integer> generic // Item<String> beans will not appear in this list @Autowired private List<Item<Integer>> intItems; 

这是如何工作的?

新的ResolvableType类提供了实际使用genericstypes的逻辑。 您可以自己使用它来轻松导航和解决types信息。 ResolvableType上的大多数方法都会自己返回ResolvableType ,例如:

 // Assuming 'field' refers to 'intItems' above ResolvableType t1 = ResolvableType.forField(field); // List<Item<Integer>> ResolvableType t2 = t1.getGeneric(); // Item<Integer> ResolvableType t3 = t2.getGeneric(); // Integer Class<?> c = t3.resolve(); // Integer.class // or more succinctly Class<?> c = ResolvableType.forField(field).resolveGeneric(0, 0); 

查看下面的链接中的示例和教程。

  • Spring Framework 4.0和Javagenerics
  • spring和自动assembly的types

希望这可以帮助你。

如果您不想升级到Spring 4,则必须按照以下名称自动assembly:

 @Autowired @Qualifier("stringItem") private Item<String> strItem; // Injects the stringItem bean @Autowired @Qualifier("integerItem") private Item<Integer> intItem; // Injects the integerItem bean 

Spring自动assembly策略在您的configuration文件(application.xml)中定义。

如果你没有定义,默认是按Type,spring注入使用JDKreflection机制。

所以列表?string? 和List?Item?types是一样的List.class,所以弹簧混淆了如何注入。

和上面的人一样,你应该用@Qualifier来告诉spring哪个bean应该被注入。

我喜欢spring configration文件来定义bean而不是Annotation。

 <bean> <property name="stringItem"> <list> <....> </list> </property> 

Spring 4.0是@Qualifier注释用法的答案。 希望这可以帮助

我相信它与generics没有任何关系……如果你注入了两个不同types的bean,那么你需要提供一个限定符来帮助Spring识别它们;

…其他地方

 @Configuration @Bean public Item stringItem() { return new StringItem(); } @Bean public Item integerItem() { return new IntegerItem(); } 

如果你有这样的非generics声明,那么你需要添加限定符来帮助Spring识别它们…

 @Autowired **@Qualifier("stringItem")** private Item item1; @Autowired **@Qualifier("integerItem")** private Item item2; 

当然,在版本4及以上版本中,Spring通过parsing器来考虑generics,它非常酷。