Spring将列表自动装配到bean中会导致NoSuchBeanDefinitionException

时间:2016-10-20 16:13:44

标签: spring autowired

在Spring 3.1.3.RELEASE项目中,我想创建一个包含某些服务枚举的列表并自动装配。

不幸的是,自动装配失败(NoSuchBeanDefinitionException),而我可以在上下文中检索bean并手动连接依赖项。

这是一个展示问题的小测试用例(使用Spring 3.1.3和JUnit):

XML上下文(int package / junk):

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="junk"/>

    <util:list id="myList" value-type="junk.GreatThings">
        <value>SUPER</value>
        <value>COOL</value>
    </util:list>

</beans>

枚举:

package junk;
public enum GreatThings {AMAZING, GREAT, SUPER, COOL}

测试类(在垃圾邮件包中 - 为清晰起见,我删除了导入内容):

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:junkcontext.xml"})  
public class TestAutowiringSupport {
    @Autowired @Qualifier("myList") List<GreatThings> greatThings;

    @Test public void testSuperCool() {
        Assert.assertThat(greatThings, hasItem(SUPER));
        Assert.assertThat(greatThings, hasItem(COOL));
    }
}

这导致NoSuchBeanDefinitionException。 我试着用一个带有bean id的@Qualifier来帮助Spring执行布线而没有任何成功。

然而,我的IDE能够自行检测接线: enter image description here

如果我使用Spring生命周期回调来获取bean并手动连接它,那么就可以了。

编译并运行良好的版本:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:junkcontext.xml"})
public class TestAutowiringSupport implements ApplicationContextAware
{

    ApplicationContext ctx;
    List<GreatThings> greatThings;

    @Override
    public void setApplicationContext(ApplicationContext ctx) throws BeansException {this.ctx = ctx;}

    @PostConstruct
    public void manualWiring() {greatThings = (List<GreatThings>) ctx.getBean("myList");}

    @Test public void testSuperCool() {
        Assert.assertThat(greatThings, hasItem(SUPER));
        Assert.assertThat(greatThings, hasItem(COOL));
    }

}

在这种情况下自动装配有什么问题?

2 个答案:

答案 0 :(得分:1)

reference documentation中所述,将@Autowired注释放在类型化集合上意味着&#34;找到给定类型的所有bean(在您的案例中为GreatThings),将它们放入在一个集合中并注入该集合&#34;。您将获得异常,因为没有声明类型为GreatThings的bean。

问题在于没有简单的方法将枚举值声明为bean。然后我再也不认为用例是诚实的。

答案 1 :(得分:1)

看起来像泛型有些问题。

使用Spring 4.1,我可以执行此代码:其中greatThings的类型为List<Object>

@Qualifier("myList")
@Autowired List<Object> greatThings;

@Test
public void testSuperCool() {
    Assert.assertThat(greatThings, Matchers.hasSize(2));
    Assert.assertThat(greatThings, Matchers.hasItem(GreatThings.SUPER));
    Assert.assertThat(greatThings, Matchers.hasItem(GreatThings.COOL));        
}