Tengo un bean Item<T>
que debe estar conectado automáticamente en una @Configuration
clase.
@Configuration
public class AppConfig {
@Bean
public Item<String> stringItem() {
return new StringItem();
}
@Bean
public Item<Integer> integerItem() {
return new IntegerItem();
}
}
Pero cuando lo 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 Autowire tipo genérico Item<T>
en Spring?
public class Parent<T> {}
subclase de clase principalpublic class Child extends Parent<Integer> { }
y ahora:Child c = new Child(); System.out.println(((ParameterizedType)c.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
se imprimiráclass java.lang.Integer
Si no desea actualizar a Spring 4, debe realizar el autowire por nombre como se muestra a continuación:
@Autowired @Qualifier("stringItem") private Item<String> strItem; // Injects the stringItem bean @Autowired @Qualifier("integerItem") private Item<Integer> intItem; // Injects the integerItem bean
fuente
StringItem
yIntegerItem
clases directamente?A continuación se muestra una solución que hice para responder a esta pregunta:
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);
fuente
La estrategia Spring Autowired se define en su archivo de configuración (application.xml).
si no lo ha definido, el valor predeterminado es por Tipo, la inyección de resorte usa el mecanismo de reflexión JDK.
entonces List? String? y List? Item ?, el tipo es el mismo List.class, por lo que Spring confundió cómo inyectar.
y como la respuesta de las personas anteriores, debe apuntar a @Qualifier para decirle a Spring qué bean debe inyectarse.
Me gusta el archivo de configuración de primavera para definir el frijol en lugar de la Anotación.
<bean> <property name="stringItem"> <list> <....> </list> </property>
fuente
Spring 4.0 es la respuesta con el uso de la anotación @Qualifier. Espero que esto ayude
fuente
Creo que no tiene nada que ver con los genéricos ... Si está inyectando dos beans diferentes del mismo tipo, debe proporcionar un calificador para ayudar a Spring a identificarlos;
... En otro lugar
@Configuration @Bean public Item stringItem() { return new StringItem(); } @Bean public Item integerItem() { return new IntegerItem(); }
Si tiene declaraciones no genéricas como estas, debe agregar un 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 resolutores, lo cual es muy bueno ...
fuente