Ich habe eine Bohne, Item<T>
die in einer @Configuration
Klasse automatisch verdrahtet werden muss .
@Configuration
public class AppConfig {
@Bean
public Item<String> stringItem() {
return new StringItem();
}
@Bean
public Item<Integer> integerItem() {
return new IntegerItem();
}
}
Aber wenn ich es versuche @Autowire Item<String>
, bekomme ich folgende Ausnahme.
"No qualifying bean of type [Item] is defined: expected single matching bean but found 2: stringItem, integerItem"
Wie soll ich Item<T>
im Frühjahr einen generischen Autowire-Typ verwenden ?
public class Parent<T> {}
Unterklasse der Elternklassepublic class Child extends Parent<Integer> { }
und jetzt:Child c = new Child(); System.out.println(((ParameterizedType)c.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
wird gedrucktclass java.lang.Integer
Wenn Sie nicht auf Spring 4 aktualisieren möchten, müssen Sie den Namen wie folgt automatisch verdrahten:
@Autowired @Qualifier("stringItem") private Item<String> strItem; // Injects the stringItem bean @Autowired @Qualifier("integerItem") private Item<Integer> intItem; // Injects the integerItem bean
quelle
StringItem
&IntegerItem
Klassen arbeiten?Unten ist eine Lösung, die ich zur Beantwortung dieser Frage gemacht habe:
List<String> listItem= new ArrayList<>(); ResolvableType resolvableType = ResolvableType.forClassWithGenerics(List.class, String.class); RootBeanDefinition beanDefinition = new RootBeanDefinition(); beanDefinition.setTargetType(resolvableType); beanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE); beanDefinition.setAutowireCandidate(true); DefaultListableBeanFactory bf = (DefaultListableBeanFactory) configurableWebApplicationContext.getBeanFactory(); bf.registerBeanDefinition("your bean name", beanDefinition); bf.registerSingleton("your bean name", listItem);
quelle
Die automatische Drahtstrategie von Spring ist in Ihrer Konfigurationsdatei (application.xml) definiert.
Wenn Sie nicht definiert haben, ist die Standardeinstellung Typ, Federeinspritzung JDK-Reflektionsmechanismus verwenden.
also Liste? String? und List? Item?, der Typ ist der gleiche List.class, also verwirrt Spring, wie man injiziert.
und wie oben Personenantwort, sollten Sie Punkt @Qualifier sein, um Frühling zu sagen, welche Bohne injiziert werden soll.
Ich mag Spring Configration File, um Bean zu definieren, anstatt Annotation.
<bean> <property name="stringItem"> <list> <....> </list> </property>
quelle
Spring 4.0 ist die Antwort mit der Verwendung der Annotation @Qualifier. Hoffe das hilft
quelle
Ich glaube, es hat nichts mit Generika zu tun ... Wenn Sie zwei verschiedene Bohnen des gleichen Typs injizieren, müssen Sie ein Qualifikationsmerkmal angeben, damit Spring sie identifizieren kann.
... Anderswo
@Configuration @Bean public Item stringItem() { return new StringItem(); } @Bean public Item integerItem() { return new IntegerItem(); }
Wenn Sie nicht generische Deklarationen wie diese haben, müssen Sie ein Qualifikationsmerkmal hinzufügen, damit Spring sie identifizieren kann ...
@Autowired **@Qualifier("stringItem")** private Item item1; @Autowired **@Qualifier("integerItem")** private Item item2;
Natürlich berücksichtigt der Frühling in Versionen 4 und höher die generischen Typen durch die Resolver, was sehr cool ist ...
quelle