【问题标题】:Spring Autowiring a list into a bean results in a NoSuchBeanDefinitionExceptionSpring将列表自动装配到bean中会导致NoSuchBeanDefinitionException
【发布时间】:2017-03-02 18:04:54
【问题描述】:

在 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 能够自行检测接线:

如果我使用 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));
    }

}

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

【问题讨论】:

  • 尝试在TestAutowiringSupport中添加@Qualifier("myList")greatThings
  • 我试过了,但它做同样的事情...... NoSuchBeanDefinitionException
  • 尝试将@Component 添加到TestAutowiringSupport

标签: spring autowired


【解决方案1】:

看起来泛型有些问题。

使用 Spring 4.1,我可以执行以下代码:greatThings 的类型为 List&lt;Object&gt;

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

【讨论】:

  • 奇怪的是 Intellij 能够检测到接线并在列表声明中提供自动完成功能。这让我觉得该设置是“正确的”,但在 Spring 3.1 中可能存在错误或严重支持。感谢您的确认。
  • 相同的代码可以用 List 执行吗???即使使用 List 我也无法在 Spring 3 中运行代码
  • @Guillaume: List&lt;GreatThings&gt; 不起作用,只有 List&lt;Object&gt; - 我试图在第二行中明确说明这一点。
【解决方案2】:

reference documentation 中所述,将@Autowired 注释放在类型化集合上意味着“找到给定类型的所有bean(在您的情况下为GreatThings),将它们放入一个集合并注入该集合”。您收到异常是因为没有声明 GreatThings 类型的 bean。

问题在于没有简单的方法将枚举值声明为 bean。再说一次,老实说,我看不到用例。

【讨论】:

    猜你喜欢
    • 2014-11-17
    • 2018-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-04
    • 2016-01-22
    • 1970-01-01
    相关资源
    最近更新 更多