Como Autowire Bean do tipo genérico no Spring?

Eu tenho um bean Item que é necessário para ser autowired em uma class @Configuration .

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

Mas quando eu tento @Autowire Item , recebo seguinte exceção.

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

Como devo autowire tipo genérico Item no Spring?

A solução simples é atualizar para o Spring 4.0, uma vez que irá considerar automaticamente os genéricos como uma forma de @Qualifier , conforme abaixo:

 @Autowired private Item strItem; // Injects the stringItem bean @Autowired private Item intItem; // Injects the integerItem bean 

De fato, você pode até mesmo autowire genéricos nesteds ao injetar em uma lista, como abaixo:

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

Como isso funciona?

A nova class ResolvableType fornece a lógica de realmente trabalhar com tipos genéricos. Você pode usá-lo para navegar facilmente e resolver informações de tipo. A maioria dos methods no ResolvableType irá retornar um ResolvableType , por exemplo:

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

Confira os exemplos e tutoriais nos links abaixo.

  • Spring Framework 4.0 e Java Generics
  • spring e Autowiring de tipos genéricos

Espero que isso ajude você.

Se você não quer atualizar para o Spring 4 você tem que autowire pelo nome como abaixo:

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

A estratégia autowired do Spring é definida em seu arquivo de configuração (application.xml).

se você não definiu, o padrão é por Tipo, o mecanismo de reflection JDK de uso de injeção de mola.

então listar? e List? Item ?, o tipo é o mesmo List.class, então confuso como injetar.

e como acima a resposta das pessoas, você deve apontar o @Qualifier para informar à primavera qual bean deve ser injetado.

Eu gosto de arquivo de confração de primavera para definir o feijão em vez de Anotação.

    <....>   

O Spring 4.0 é a resposta com o uso da anotação @Qualifier. Espero que isto ajude

Eu acredito que não tem nada a ver com genéricos … Se você está injetando dois tipos diferentes do mesmo tipo, então você precisa fornecer um qualificador para ajudar o Spring a identificá-los;

… Em outro lugar

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

Se você tem uma declaração não genérica como essa, você precisa adicionar o qualificador para ajudar a Spring a identificá-la …

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

Claro, nas versões 4 e acima, a primavera considera os Generic Types através dos resolvers, o que é muito legal …