代码之家  ›  专栏  ›  技术社区  ›  Paul McKenzie

使用UTIL模式自动连接列表时,不会出现UCHBeanDefinitionException

  •  89
  • Paul McKenzie  · 技术社区  · 16 年前

    我有一个bean,我想使用spring-util名称空间用一个命名列表注入它。 <util:list id="myList"> 但是Spring正在寻找一个字符串类型的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)
    

    这让我感到困惑,而不是像我想象的那样,这将是预期的工作方式。

    3 回复  |  直到 10 年前
        1
  •  169
  •   skaffman    14 年前

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

    也可以提供 特定类型的豆子 ApplicationContext 通过添加 字段或方法的注释 需要该类型的数组…

    同样适用于类型化集合…

    换句话说,通过说 @Autowired @Qualifier("myList") List<String> 你实际上是在要求“给我所有豆子的清单” java.lang.String 具有限定符“mylist”的。

    解决方案见 3.11.3. Fine-tuning annotation-based autowiring with qualifiers :

    如果你想表达 由名称驱动的注释注入, 不主要使用 @Autowired -甚至 如果技术上能够参考 通过 @Qualifier 价值观。相反,更喜欢JSR-250 @Resource 注释,即 在语义上定义为标识 特定目标成分 唯一名称,具有声明的类型 与匹配无关 过程。

    这是一个特殊的结果 语义差异,豆子 定义为集合或 无法通过注入映射类型 @自动连线 因为类型匹配不是 适用于他们。 使用 @资源 对于这种豆子,指 特定的收集/映射bean 唯一的名称。

    所以在测试中使用这个,它会很好地工作:

    @Resource(name="myList") private List<String> stringList;
    
        2
  •  0
  •   juliangonzalez    10 年前

    可能发生的另一件事是,您正在自动连接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 类中的注释。

        3
  •  -1
  •   bazwilliams    13 年前

    如果使用JBoss6.1,我发现@resource注释导致部署失败(细节被省略,因为与问题无关)。

    所有应用程序服务器的一个通用替代方法是使用@inject注释( JSR-330 )