java spring中的泛型集合依赖

时间:2016-09-05 11:53:19

标签: java spring

给出以下代码(使用spring 3.2.5):

@org.springframework.context.annotation.Configuration
public class MyConfiguration {

    @Bean
    public MyClass myClass(@Qualifier("messageFeeders") List<MessageFeeder> messageFeeders) {
        return new MyClass(messageFeeders);
    }

    @Bean
    public MessageFeederSubclassOne messageFeeder1() {
        return new MessageFeederSubclassOne();
    }

    @Bean
    public MessageFeederSubclassTwo messageFeeder2() {
        return new MessageFeederSubclassTwo();
    }

    @Bean
    @Qualifier("messageFeeders")
    public List<MessageFeeder> messageFeeders(MessageFeederSubclassOne messageFeeder1, MessageFeederSubclassTwo messageFeeder2) {
        return ImmutableList.of(messageFeeder1, messageFeeder2);
    }
}

我得到了这个例外:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myClass' defined in class path resource [com/company/configuration/MyConfiguration.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [java.util.List]: : No qualifying bean of type [com.company.messagebroker.MessageFeeder] found for dependency [collection of com.company.messagebroker.MessageFeeder]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Qualifier(value=messageFeeders)}
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:738)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.company.messagebroker.MessageFeeder] found for dependency [collection of com.company.messagebroker.MessageFeeder]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Qualifier(value=messageFeeders)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:988)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:816)

现在,我意识到spring正在尝试找到MessageFeeder类型的bean并将它们全部填入此列表中,但我希望限定符会强制它实际注入我自己定义的列表。

查看DefaultListableBeanFactory代码,它似乎完全忽略了限定符。

另外,为什么会失败?即使忽略限定符,它不应该检测从MessageFeeder继承并使用它们的两个bean吗?

我不想更改messageFeeders bean,因为我不是唯一一个使用它的人。有没有简单的方法让Spring考虑限定符?

3 个答案:

答案 0 :(得分:1)

尝试使用@Resource因为它可以解决问题

@Bean
@Resource(name = "messageFeeders") 
public MyClass myClass(List<MessageFeeder> messageFeeders) {
    return new MyClass(messageFeeders);
}

答案 1 :(得分:1)

以下是您的解决方案:

@Bean
@Autowired
@Qualifier("messageFeeders")`
public MyClass myClass(List<MessageFeeder> messageFeeders) 
{
    return new MyClass(messageFeeders);`
}

说明:

我首先尝试在Spring 4.3.2版本上进行操作,它的工作方式与您定义的方式相当。但是,我将Spring依赖项更改为版本3.2.5,并且我收到了您的异常。

@Autowired是通过注释注入bean的正确方法,它按类型执行。在@Autowired注释的情况下,IOC容器通过类型识别注入bean。

现在,如果我们的IOC容器中有多个相同类型的bean,该怎么办?怎么知道要注入哪个bean?

简单地说,通过@Qualifier注释。

但您仍然需要使用@Autowired注释。

答案 2 :(得分:0)

为消息馈送器列表创建一个新的包装器类,更改bean创建以使用新类,然后将“@Autowired”添加到构造函数调用中

class MessageFeederList extends ArrayList<MessageFeeder>{}

@Bean
public MessageFeederList messageFeeders(
    MessageFeederSubclassOne messageFeeder1, 
    MessageFeederSubclassTwo messageFeeder2){
    return ImmutableList.of(messageFeeder1, messageFeeder2);
}

@Bean
public MyClass myClass(@Autowired MessageFeederList messageFeeders) {
    return new MyClass(messageFeeders);
}