为什么春天没有使用通用限定符注入?

时间:2015-10-15 04:29:18

标签: java spring generics

这是我的配置类

@Configuration
class Factories {

    @Bean
    Collection<Log> logs() {
        List<Log> logs = new ArrayList<>();
        for ( int i = 0; i < 10; i++ ) { // gross example code
            Log log = new Log();
            log.setEntry( RandomStringUtils.randomAlphabetic( 10 ) );
            logs.add( log );
        }
        return logs;
    }
}

这就是我试图自动装配它的方式

@Service
@Transactional
public class LogService {

    private final LogRepository repository;
    private final ObjectFactory<Instant> now;
    private final Collection<Log> logs;

    @Autowired
    LogService( final LogRepository repository, final ObjectFactory<Instant> now, final Collection<Log> logs ) {
        this.repository = repository;
        this.now = now;
        this.logs = logs;
    }

但是我得到了这个例外

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.xenoterracide.example.log.Log] found for dependency [collection of com.xenoterracide.example.log.Log]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1326)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1024)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:967)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
... 24 more

according to the documentation我认为这应该有效。 Here's my full code in case you need it。我误解了文档吗?

1 个答案:

答案 0 :(得分:3)

鉴于@Autowired List<Something>,Spring会查找您在Something中定义的ApplicationContext个bean,并尝试将它们全部自动装入目标。 The documentation states

  

作为这种语义差异的一个特定结果,是   自己定义为集合或地图类型不能注入   通过@Autowired ,因为类型匹配不适用   给他们。对这些bean使用@Resource,参考具体的   按唯一名称收集或映射bean。

在你的情况下,你有

@Autowired
LogService(/* ... */ final Collection<Log> logs ) {

但没有Log个bean。所以它抱怨

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.xenoterracide.example.log.Log] found for dependency [collection of com.xenoterracide.example.log.Log]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}

您似乎想要的是直接注入Collection<Log>类型的bean。 Spring可以使用javax.annotation.Resource注释执行此操作。不幸的是,该注释并不适用于构造函数。

您需要注释(更改为非final)字段或添加setter方法并注释。

@Resource
private Collection<Log> logs;

@Resource
public void setLogs(Collection<Log> logs) {
    this.logs = logs;
}