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

Java Spring@Autowired是按名称还是按类型注入bean?,java,spring,configuration,code-injection,autowired,Java,Spring,Configuration,Code Injection,Autowired,我正在读《初春》(威利出版社)的书。第二章有一个例子 关于Java配置和@Autowired。它提供了这个@配置类 @Configuration public class Ch2BeanConfiguration { @Bean public AccountService accountService() { AccountServiceImpl bean = new AccountServiceImpl(); return bean;

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

@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的名字,
@Autowired
基本上是关于类型驱动注入的 带有可选语义限定符
。这意味着限定符值, 即使使用bean名称回退,也始终具有狭义语义 在类型匹配集内;它们在语义上不表示 对唯一bean id的引用

所以,不,这不是bug,这是预期的行为。如果按类型自动连线找不到单个匹配的bean,则bean id(名称)将用作回退。

解释了这一点

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


所以,不,这不是bug,这是预期的行为。如果by类型自动连线找不到一个匹配的bean,则bean id(名称)将用作备用项。

IMO这是一个非常危险和糟糕的设计。注入资源的名称不应影响注入的注册方式。现在,所有的东西都是通过场的名称耦合的?类应该可以随意命名变量/字段,而不考虑DI。在设计类时,DI应该是“幕后的”,而不是在前面和中心。我也不同意
@Autowired
注释在课堂上有任何位置。同样,DI应该是一种预先考虑的方法,并在应用程序级别进行初始化。链下游的类应该没有DI的概念。IMO这是一个非常危险和糟糕的设计。注入资源的名称不应影响注入的注册方式。现在,所有的东西都是通过场的名称耦合的?类应该可以随意命名变量/字段,而不考虑DI。在设计类时,DI应该是“幕后的”,而不是在前面和中心。我也不同意
@Autowired
注释在课堂上有任何位置。同样,DI应该是一种预先考虑的方法,并在应用程序级别进行初始化。在链的后面的类不应该有DI的概念。我完全理解你为什么会被这搞糊涂——因为。我完全理解你为什么会被这搞糊涂——因为。