type sirve que para generic autowire java spring generics autowired spring-annotations

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