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

Lid*_*vic 17 java configuration spring code-injection 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

和这个普通的bean类

public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountDao accountDao;

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

Sot*_*lis 16

文档解释了这个

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

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

  • IMO 这是一个非常危险和糟糕的设计。注入资源的名称应该与注入的注册方式无关。现在,所有的东西都是通过字段的名称来耦合的?类应该可以随意命名变量/字段,而无需考虑 DI。在设计类时,DI 应该是“幕后”,而不是前台和中心。我也不同意 `@Autowired` 注释在课堂上有任何位置。同样,DI 应该是在应用程序级别预先考虑和初始化的。链下游的类应该没有 DI 的概念。 (4认同)