2015-10-15 45 views
1

这是我的配置类为什么spring不使用泛型限定符进行注入?

@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。我误解了文档吗?

+0

不要创建'Log'豆作为收藏。相反,使用自己的'@ Bean'注释创建每个'Log'。 '收集'注射应该工作。 – RJo

+0

@ajb [它们是](https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Method.html#getGenericReturnType--)和Spring。 –

+0

我不知道那个......我猜太多认真地对待“类型删除”了...... – ajb

回答

3

鉴于@Autowired一个List<Something>,春天会寻找尽可能多的Something豆,你在你的ApplicationContext定义,并试图将它们全部自动装配到目标。 The documentation states

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

你的情况,你有

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

但没有Log豆。所以,抱怨

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>类型的豆。 Spring可以通过javax.annotation.Resource注释来实现。不幸的是,该注释对构造函数不起作用。

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

@Resource 
private Collection<Log> logs; 

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

好奇,对于这种情况,“@Inject”的行为方式与“@ Autowired”相同吗? – xenoterracide

+0

@xenoterracide是的,'AutowiredAnnotationBeanPostProcessor'处理这两个。 '@ Resource'由'CommonAnnotationBeanPostProcessor'处理。 –

相关问题