如何在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,它非常酷。
- 如何在春季做条件自动布线?
- 在@RequestParam中绑定列表
- 使用@PropertySource批注时,@Value未parsing。 如何configurationPropertySourcesPlaceholderConfigurer?
- 为什么我们不能在spring自动assembly静态字段?
- 在多个项目/模块中使用多个属性文件(通过PropertyPlaceholderConfigurer)
- 弹簧启动默认H2 jdbc连接(和H2控制台)
- Spring MVC中的@RequestParam处理可选参数
- spring @Controller和@RestController注释的区别
- Spring Java Config:如何用运行时参数创build一个原型范围的@Bean?