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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30360589/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 16:59:56  来源:igfitidea点击:

Does Spring @Autowired inject beans by name or by type?

javaspringconfigurationcode-injectionautowired

提问by Lidovic

I am reading beginning spring (wiley press) book. In chapter 2 there is an example about Java configuration and @Autowired. It provides this @Configurationclass

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

and this regular bean class

和这个普通的豆类

public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountDao accountDao;

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

When I run the code, it works. But I expected an exception because I have defined 2 beans with the same type in the configuration.

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

I realized it works like this:

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

  • if Spring encounters multiple beans with same type it checks field name.
    • if it finds a bean with the name of the target field, it injects that bean into the field.
  • 如果 Spring 遇到多个相同类型的 bean,它会检查字段名称。
    • 如果它找到具有目标字段名称的 bean,则将该 bean 注入该字段。

Isn't this wrong? Is there a bug in Spring's handling of Java configuration?

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

采纳答案by Sotirios Delimanolis

The documentationexplains this

文档解释了这个

For a fallback match, the bean name is considered a default qualifier value.Thus you can define the bean with an id "main" instead of the nested qualifier element, leading to the same matching result. However, although you can use this convention to refer to specific beans by name, @Autowiredis fundamentally about type-driven injection with optional semantic qualifiers. This means that qualifier values, even with the bean name fallback, always have narrowing semantics within the set of type matches; they do not semantically express a reference to a unique bean id

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

So, no, it's not a bug, that is the intended behavior. The bean id (name) will be used as a fallback if a by-type autowiring doesn't find a single matching bean.

所以,不,这不是错误,这是预期的行为。如果按类型自动装配没有找到单个匹配的 bean,则 bean id(名称)将用作后备。