java - sirve - Cómo Autowire Bean de tipo genérico<T> en primavera?
autowired generic type (5)
Creo que no tiene nada que ver con los genéricos ... Si está inyectando dos tipos diferentes del mismo tipo, debe proporcionar un calificador para ayudar a Spring a identificarlos;
... En otros lugares
@Configuration
@Bean
public Item stringItem() {
return new StringItem();
}
@Bean
public Item integerItem() {
return new IntegerItem();
}
Si tiene declaraciones no genéricas como estas, entonces necesita agregar calificador para ayudar a Spring a identificarlas ...
@Autowired
**@Qualifier("stringItem")**
private Item item1;
@Autowired
**@Qualifier("integerItem")**
private Item item2;
Por supuesto, en las versiones 4 y superiores Spring considera los tipos genéricos a través de los resolvedores, lo que es muy bueno ...
Tengo un Item<T>
frijol que se requiere para ser auto-conectado en una clase @Configuration
.
@Configuration
public class AppConfig {
@Bean
public Item<String> stringItem() {
return new StringItem();
}
@Bean
public Item<Integer> integerItem() {
return new IntegerItem();
}
}
Pero cuando intento @Autowire Item<String>
, obtengo la siguiente excepción.
"No qualifying bean of type [Item] is defined: expected single matching bean but found 2: stringItem, integerItem"
¿Cómo debo autocausar el Item<T>
tipo genérico Item<T>
en primavera?
La estrategia de autoenlace de primavera se define en su archivo de configuración (application.xml).
si no está definido, el valor predeterminado es por Tipo, inyección de primavera utilice el mecanismo de reflejo JDK.
Entonces List? String? y List? Item ?, el tipo es el mismo List.class, por lo que Spring confunde cómo inyectar.
y como respuesta de las personas anteriores, debe señalar @Qualifier para indicar a la primavera qué bean debe inyectarse.
Me gusta el archivo de configuración de primavera para definir bean en lugar de Annotation.
<bean>
<property name="stringItem">
<list>
<....>
</list>
</property>
La solución simple es actualizar a Spring 4.0 ya que automáticamente considerará los genéricos como una forma de @Qualifier
, como se muestra a continuación:
@Autowired
private Item<String> strItem; // Injects the stringItem bean
@Autowired
private Item<Integer> intItem; // Injects the integerItem bean
De hecho, incluso puede autoaumentar genéricos anidados cuando se inyecta en una lista, como se muestra a continuación:
// 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;
¿Cómo funciona esto?
La nueva clase ResolvableType
proporciona la lógica de trabajar realmente con tipos genéricos. Puede usarlo usted mismo para navegar y resolver fácilmente la información de tipo. La mayoría de los métodos en ResolvableType
devolverán un ResolvableType
, por ejemplo:
// 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);
Consulte los ejemplos y tutoriales en los enlaces a continuación.
Espero que esto te ayude.
Si no desea actualizar a Spring 4, tiene que autoconectarse por su nombre de la siguiente manera:
@Autowired
@Qualifier("stringItem")
private Item<String> strItem; // Injects the stringItem bean
@Autowired
@Qualifier("integerItem")
private Item<Integer> intItem; // Injects the integerItem bean
Spring 4.0 es la respuesta con el uso de la anotación @Qualifier. Espero que esto ayude