Spring @Autowired是按名称还是按类型注入bean?

我正在读初春(威利出版社)的书。 在第2章中有一个关于Java配置和@Autowired的示例。 它提供了这个@Configuration

 @Configuration public class Ch2BeanConfiguration { @Bean public AccountService accountService() { AccountServiceImpl bean = new AccountServiceImpl(); return bean; } @Bean public AccountDao accountDao() { AccountDaoInMemoryImpl bean = new AccountDaoInMemoryImpl(); //depedencies of accountDao bean will be injected here... return bean; } @Bean public AccountDao accountDaoJdbc() { AccountDaoJdbcImpl bean = new AccountDaoJdbcImpl(); return bean; } } 

和这个普通的bean类

 public class AccountServiceImpl implements AccountService { @Autowired private AccountDao accountDao; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } ... } 

当我运行代码时,它可以工作。 但我期望一个例外,因为我在配置中定义了两个具有相同类型的bean。

我意识到它的工作原理如下:

  • 如果Spring遇到多个具有相同类型的bean,则会检查字段名称。
    • 如果它找到一个具有目标字段名称的bean,它会将该bean注入该字段。

这不对吗? Spring处理Java配置是否存在错误?

文档解释了这一点

对于回退匹配, bean名称被视为默认限定符值。 因此,您可以使用id“main”而不是嵌套的限定符元素来定义bean,从而得到相同的匹配结果。 但是,虽然您可以使用此约定来按名称引用特定bean,但@Autowired基本上是关于具有可选语义限定符的类型驱动注入 。 这意味着即使使用bean名称回退,限定符值在类型匹配集中也总是具有缩小的语义; 它们在语义上不表示对唯一bean id的引用

所以,不,这不是一个错误,这是预期的行为。 如果by-type autowiring没有找到单个匹配bean,则bean id(name)将用作后备。