Как Autowire Bean универсального типа весной?
у меня есть в зернах Item<T>
который требуется для автоматического подключения в @Configuration
класса.
@Configuration
public class AppConfig {
@Bean
public Item<String> stringItem() {
return new StringItem();
}
@Bean
public Item<Integer> integerItem() {
return new IntegerItem();
}
}
но когда я пытаюсь @Autowire Item<String>
, Я получаю следующее исключение.
"No qualifying bean of type [Item] is defined: expected single matching bean but found 2: stringItem, integerItem"
как я должен Autowire generic type Item<T>
весной?
5 ответов:
простое решение-перейти на Весна 4.0 поскольку он автоматически будет рассматривать дженерики как форму
@Qualifier
, как показано ниже:@Autowired private Item<String> strItem; // Injects the stringItem bean @Autowired private Item<Integer> intItem; // Injects the integerItem bean
Infact, вы можете даже autowire вложенные дженерики при введении в список, как показано ниже:
// 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;
как это работает?
новая
ResolvableType
класс содержит логику работы с универсальными типами. Вы можете использовать его самостоятельно, чтобы легко перемещаться и решать тип информация. Большинство методов наResolvableType
вернутся сами собойResolvableType
, например:// 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);
ознакомьтесь с примерами и учебниками по ссылкам ниже.
надеюсь, что это поможет вам.
Если вы не хотите переходить на Spring 4, вам нужно autowire по имени, как показано ниже:
@Autowired @Qualifier("stringItem") private Item<String> strItem; // Injects the stringItem bean @Autowired @Qualifier("integerItem") private Item<Integer> intItem; // Injects the integerItem bean
стратегия Spring autowired определена в вашем файле конфигурации(приложение.XML.)
Если вы не определили, по умолчанию по типу, spring inject использует механизм отражения JDK.
такой список?Струна? а список?Предмет?, тип тот же список.класс, поэтому весной путают, как вводить.
и, как указано выше, вы должны указать @ Qualifier, чтобы сообщить spring, какой Боб должен быть введен.
Я люблю весну файла конфигурации для определения зерен, а затем аннотации.
<bean> <property name="stringItem"> <list> <....> </list> </property>
Я считаю, что это не имеет ничего общего с обобщениями... Если вы вводите два разных Боба одного типа, вам нужно предоставить квалификатор, чтобы помочь Spring идентифицировать их;
... В другом месте
@Configuration @Bean public Item stringItem() { return new StringItem(); } @Bean public Item integerItem() { return new IntegerItem(); }
Если у вас есть не общие объявления, как эти, то вам нужно добавить квалификатор, чтобы помочь Spring идентифицировать их...
@Autowired **@Qualifier("stringItem")** private Item item1; @Autowired **@Qualifier("integerItem")** private Item item2;
конечно, в версиях 4 и выше spring рассматривает общие типы через резольверы, что очень круто...