Автоматическое подключение списка с помощью схемы util дает NoSuchBeanDefinitionException
у меня есть боб, который я хочу ввести с именованным списком, используя пространство имен Spring util <util:list id="myList">
но весна ищет коллекцию бобов типа String вместо этого. Мой сломанный тест:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class ListInjectionTest {
@Autowired @Qualifier("myList") private List<String> stringList;
@Test public void testNotNull() {
TestCase.assertNotNull("stringList not null", stringList);
}
}
мой контекст:
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<util:list id="myList">
<value>foo</value>
<value>bar</value>
</util:list>
</beans>
но я
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [java.lang.String] found for dependency [collection of java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=myList)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:726)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:571)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:412)
что меня скорее озадачивает, поскольку я полагал, что это будет так, как ожидалось.
3 ответа:
это связано с довольно неясной частью поведения @Autowired, указанной в 3.11.2. @Autowired:
также возможно обеспечить все фасоль определенного типа из
ApplicationContext
путем добавления аннотация к полю или методу, который ожидает массив такого типа...то же самое относится и к типизированным коллекциям...
другими словами, говоря
@Autowired @Qualifier("myList") List<String>
, вы на самом деле просите "дайте мне список всех бобов типаjava.lang.String
которые имеют квалификатор "myList".решение упомянуто в 3.11.3. Точная настройка аннотации на основе автопроводки с квалификаторами:
если вы намерены выразить аннотация-управляемая впрыска по имени, не используйте в первую очередь
@Autowired
- даже если технически способен ссылаться к имени Боба через@Qualifier
ценности. Вместо этого предпочтите JSR-250@Resource
аннотированию семантически определенными для идентификации специфический целевой компонент своим уникальное имя, с объявленным типом не имеет значения для сопоставления процесс.как конкретное следствие этого семантическое различие, бобы, которые являются сами определяются как коллекция или тип карты не может быть введен через
@Autowired
так как тип соответствия не является правильно применимо к ним. использовать@Resource
для таких бобов, ссылаясь на конкретная коллекция / карта bean by уникальный имя.так что используйте это в своем тесте, и он отлично работает:
@Resource(name="myList") private List<String> stringList;
еще одна вещь, которая может произойти, заключается в том, что вы автоматически подключаете свойство Боба. В таком случае вам не нужно автоматически подключать его, а просто создать метод setter и использовать тег свойства в определении bean (при использовании xml) пример:
<bean id="cleaningUpOldFilesTasklet" class="com.example.mypackage.batch.tasklets.CleanUpOldFilesTasklet"> <property name="directoriesToClean"> <list> <value>asfs</value> <value>fvdvd</value> <value>sdfsfcc</value> <value>eeerer</value> <value>rerrer</value> </list> </property> </bean>
и класс:
public class CleanUpOldFilesTasklet extends TransferingFilesTasklet implements Tasklet{ private long pastMillisForExpiration; private final String dateFormat = "MM.dd"; Date currentDate = null; List<String> directoriesToClean; public void setDirectoriesToClean(List<String> directories){ List<String> dirs = new ArrayList<>(); for(String directory : directories){ dirs.add(getSanitizedDir(directory)); } this.directoriesToClean = dirs; }
посмотреть, нет
@Autowired
аннотаций в классе.
при использовании JBoss 6.1 я обнаружил, что аннотация @Resource вызвала сбой моего развертывания (деталь опущена как не относящаяся к вопросу).
общий для всех серверов приложений является использование аннотации @Inject (JSR-330).