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

我正在阅读春天开始(威利出版社)的书。在第 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;
    }
}

和这个常规的豆类

public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountDao accountDao;

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }
    ...
}

当我运行代码时,它可以工作。但是我预料到了一个异常,因为我在配置中定义了2个具有相同类型的bean。

我意识到它的工作原理是这样的:

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

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


答案 1

文档对此进行了说明

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

所以,不,这不是一个错误,这是预期的行为。如果按类型自动布线找不到单个匹配的 Bean,则 Bean ID(名称)将用作回退。


答案 2

推荐