Autowiring коллекции через конструктор с Spring
У меня есть то, что кажется простой проблемой, как указано в названии. Вот такой класс, который у меня есть:
public class Foo {
@Autowired
public Foo(@Qualifier("bar") Set<String> bar) {
// ...
}
}
Что я пытаюсь запустить со следующим контекстом spring:
<context:annotation-config />
<util:set id="bar">
<value>tata</value>
<value>titi</value>
<value>toto</value>
</util:set>
<bean id="foo" class="Foo" />
Это не работает с:
Нет соответствия bean типа [java.lang.String] найдено для зависимость [сбор java.lang.String]: ожидается не менее 1 bean, который квалифицируется как autowire кандидат на эту зависимость. Аннотации зависимостей: {@Org.springframework.beans.factory.annotation.Qualifier(value = бар)}
Обратите внимание, что если я добавлю другие параметры в свой конструктор, он отлично работает. Если я использую инъекцию сеттера, он работает нормально. Я уверен, что мне не хватает чего-то очевидного... знаете ли вы что?
Ответы
Ответ 1
Коллекции Autowiring невозможны с помощью аннотации @Autowired
. Автоукрепляемая коллекция означает "предоставлять все beans определенного типа". Используя аннотацию JSR-250 @Resource
, вы можете объявить, что хотите, чтобы ресурс вводился по его имени, а не по типу. Или вы явно вводите зависимость.
[...] beans, которые сами по себе определяются как тип коллекции или карты, не могут быть введены через @Autowired
, поскольку сопоставление типов не относится к ним надлежащим образом. Используйте @Resource
для такого beans, ссылаясь на конкретную коллекцию/карту bean по уникальному имени.
Подробнее см. документацию Spring.
Ответ 2
Как утверждают другие, невозможно использовать @Autowired для строк и коллекций String. Вы можете использовать @Value с spring EL, предполагая, что у вас есть spring в версии 3:
public class Foo {
@Autowired
public Foo(@Value("#{bar}") Set<String> bar) {
// ...
}
}
Ответ 3
Я думаю, это потому, что Spring интерпретирует autowiring коллекции как "дайте мне все beans типа String
", а не "дайте мне bean, который представляет собой коллекцию String
", Сообщение об ошибке поддерживает эту идею.
Я не думаю, что вы можете использовать autwiring для этого. Если вы не вручную подключите его в XML, я могу предложить следующее:
public class Foo {
private @Resource Set<String> bar;
}
Ответ 4
У меня была такая же проблема и был вдохновлен @rembisz answer. Этот ответ не работал над моей версией Spring (4.1.3). Когда я проверил документацию Spel на ссылках bean, я нашел другой синтаксис SpEL для выражения ссылок bean в значениях, me - @beanname
. Таким образом, для меня работал следующий код:
public class Foo {
@Autowired
public Foo(@Value("#{@bar}") Set<String> bar) {
// ...
}
}