Spring将列表自动关联到bean中会导致NoSuchBeanDefinitionException

Spring将列表自动关联到bean中会导致NoSuchBeanDefinitionException,spring,autowired,Spring,Autowired,在Spring3.1.3.RELEASE项目中,我想创建一个包含某个枚举的列表,并将其自动关联到某个服务 不幸的是,自动连接失败(NoSuchBeanDefinitionException),而我可以在上下文中检索bean并手动连接依赖项 下面是一个小测试用例,展示了这个问题(使用Spring3.1.3和JUnit): XML上下文(int-package/junk): <beans xmlns="http://www.springframework.org/schema/beans"

在Spring3.1.3.RELEASE项目中,我想创建一个包含某个枚举的列表,并将其自动关联到某个服务

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

下面是一个小测试用例,展示了这个问题(使用Spring3.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));
    }
}
@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));
    }

}
测试类(包内垃圾-为了清晰起见,我删除了导入):

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

}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(位置={“classpath*:junkcontext.xml”})
公共类TestAutowiringSupport{
@Autowired@Qualifier(“myList”)列出了大量内容;
@测试公共void testSuperCool(){
Assert.assertThat(greatThings,hasItem(SUPER));
Assert.assertThat(greatThings,hasItem(COOL));
}
}
这将导致NoSuchBeanDefinition异常。 我尝试在bean id中添加一个@Qualifier来帮助Spring执行连接,但没有成功

但是,我的IDE能够自行检测接线:

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

编译和运行良好的版本:

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

}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(位置={“classpath*:junkcontext.xml”})
公共类TestAutowiringSupport实现ApplicationContextAware
{
应用上下文ctx;
列出伟大的事物;
@凌驾
public void setApplicationContext(ApplicationContext ctx)抛出BeansException{this.ctx=ctx;}
@施工后
public void manualWiring(){greatThings=(List)ctx.getBean(“myList”);}
@测试公共void testSuperCool(){
Assert.assertThat(greatThings,hasItem(SUPER));
Assert.assertThat(greatThings,hasItem(COOL));
}
}
这种情况下自动接线有什么问题

如中所述,将
@Autowired
注释放置在键入的集合上意味着“找到给定类型的所有bean(
GreatThings
),将它们放入集合并注入该集合”。您得到异常是因为没有声明类型为
GreatThings
的bean


问题是没有简单的方法将枚举值声明为bean。老实说,我也不认为这个用例有问题。

看起来泛型有问题

使用Spring4.1,我能够执行以下代码:其中
greatThings
属于
List

@限定符(“myList”)
@自动连线列表;
@试验
公共超冷{
Assert.assertThat(greatThings,Matchers.hasSize(2));
Assert.assertThat(greatThings,Matchers.hasItem(greatThings.SUPER));
Assert.assertThat(greatThings,Matchers.hasItem(greatThings.COOL));
}

尝试将
@限定符(“myList”)
添加到
TestAutowiringSupport
中的
greatThings
中,我已经尝试过了,但它做的事情是一样的。。。nosuchbeandefinitionexception将@Component添加到
TestAutowiringSupport
classtry奇怪的是Intellij能够检测到布线并在列表声明中提供自动完成功能。这让我感觉到设置是“正确的”,但可能在Spring3.1中被窃听或支持不好。感谢您的确认。相同的代码是否可以在列表中执行???我无法在Spring3中运行代码,即使使用List@Guillaume:
List
不起作用,只有
List
-我试图在第二行的答案中明确这一点。