使用util模式自动连接List会产生NoSuchBeanDefinitionException

时间:2009-09-01 16:03:36

标签: java spring

我有一个bean,我想使用Spring util namespace <util:list id="myList">注入一个命名列表,但是Spring正在寻找一个String类型的bean集合。我的破坏测试是:

@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)

令我感到困惑的是,我认为这将是预期的方式。

2 个答案:

答案 0 :(得分:169)

这是由于3.11.2. @Autowired中指定的@Autowired行为的一个相当模糊的部分:

  

也可以提供全部   来自的特定类型的豆类   ApplicationContext添加   对该字段或方法的注释   期望一个这种类型的数组...

     

同样适用于打字的收藏......

换句话说,通过说@Autowired @Qualifier("myList") List<String>,你实际上要求“给我列出具有限定符”myList“的java.lang.String类型的所有bean。

3.11.3. Fine-tuning annotation-based autowiring with qualifiers中提到了解决方案:

  

如果你打算表达   按名称注释驱动的注入,   不要主要使用@Autowired - 甚至   如果技术上能够参考   通过@Qualifier到bean名称   值。相反,更喜欢JSR-250   @Resource注释   语义定义来识别一个   特定目标组成部分   唯一名称,具有声明的类型   与匹配无关   过程

     

作为其具体结果   语义差异,豆类是   自己定义为集合或   地图类型不能通过注入   @Autowired因为类型匹配不是   适用于他们。使用   @Resource对于这样的bean,指的是   特定的集合/映射bean   唯一的名字。

所以在你的测试中使用它,它工作正常:

@Resource(name="myList") private List<String> stringList;

答案 1 :(得分:0)

可能发生的另一件事是你正在自动装配bean的属性。在这种情况下,您不需要自动装配它,但只需创建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注释。