Comment générer automatiquement un bean de type générique au spring?

J’ai un Item bean Item qui doit être automatiquement généré dans une classe @Configuration .

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

Mais quand j’essaie de @Autowire Item , j’obtiens l’exception suivante.

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

Comment dois-je utiliser le type générique Item au spring?

Une solution simple consiste à passer à Spring 4.0, car il considérera automatiquement les génériques comme une forme de @Qualifier , comme ci-dessous:

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

En fait, vous pouvez même envoyer des génériques nesteds lorsque vous injectez dans une liste, comme ci-dessous:

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

Comment ça marche?

La nouvelle classe ResolvableType fournit la logique de travailler avec des types génériques. Vous pouvez l’utiliser vous-même pour naviguer facilement et résoudre les informations de type. La plupart des méthodes de ResolvableType elles-mêmes un ResolvableType , par exemple:

 // 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); 

Consultez les exemples et tutoriels ci-dessous.

  • Spring Framework 4.0 et Java Generics
  • Printemps et Autowiring des types génériques

J’espère que cela vous aidera.

Si vous ne voulez pas passer à Spring 4, vous devez vous identifier par le nom ci-dessous:

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

La stratégie Spring Print est définie dans votre fichier de configuration (application.xml).

Si vous ne définissez pas, la valeur par défaut est par type, le mécanisme d’injection JDK reflète le spring.

so List? Ssortingng? et List? Item?, le type est identique à List.class, donc Spring confond comment injecter.

Et comme la réponse ci-dessus, vous devriez être @Qualifier pour indiquer au spring quel haricot doit être injecté.

J’aime le fichier de config de spring pour définir le haricot plutôt que l’annotation.

    < ....>   

Spring 4.0 est la réponse avec l’utilisation de l’annotation @Qualifier. J’espère que cela t’aides

Je crois que cela n’a rien à voir avec les génériques … Si vous injectez deux grains différents du même type, vous devez fournir un qualificatif pour aider Spring à les identifier;

… Autre part

 @Configuration @Bean public Item ssortingngItem() { return new SsortingngItem(); } @Bean public Item integerItem() { return new IntegerItem(); } 

Si vous avez des déclarations non génériques comme celles-ci, vous devez append un qualificatif pour aider Spring à les identifier …

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

Bien sûr, dans les versions 4 et supérieures, spring considère les types génériques à travers les résolveurs, ce qui est très cool …