【问题标题】:@AutoWired without @Qualifier没有@Qualifier 的@AutoWired
【发布时间】:2019-05-11 21:52:11
【问题描述】:

如果有两个相同类型但名称不同的 bean。如果我们在变量上添加 @Qualifier ,是否会根据名称自动装配 bean?我在文档中看到,“作为后备 Spring 使用 bean 名称作为默认限定符值”。

@Component
class A{
}

@Component
class B extends A{
}

class C{

    @AutoWired
    A a;

//Will a be of type class A, even without @Qualifier...?
}

【问题讨论】:

  • C 类中的字段是 B 类型的,所以它不可能将 bean A 放在那里,因为它不能分配给 @987654325 类型的变量@.
  • 对....没想到这一点..假设它是A型..

标签: spring spring-boot autowired


【解决方案1】:

如果有两个相同类型但名称不同的 bean。如果我们不在变量上添加@Qualifier,是否会根据名称自动装配 bean?

@Autowire 首先关心类型,然后关心名称。你会得到异常说有多个候选注入,而预期只有 1 个。

@Resource另一方面,先关心名字,后输入。

【讨论】:

  • 所以 spring Autowired 只查看类型,如果有两个相同类型的 bean,它会立即抛出异常,甚至不检查名称..?认为我没有使用限定符
  • 不自​​动连线... 1.按类型匹配 2.按限定符限制 3.按名称匹配
  • @pavan 我没有说它“只看类型”。而是匹配优先级的问题。我将改写它,因为它确实可以这样理解。
  • 那么回到我在问题中给出的示例,'a' 会有一个类型为 'A' 的实例,没有限定符吗?
【解决方案2】:

在这种情况下,B 将被注入,因为有一个 A 和一个 B 供 Spring 选择,其中只有一个与 @Autowired 字段要求的匹配(类 B , 因为A 不能分配给B)。

但是,如果您有两个 B,则必须对其进行限定或将其中一个标记为主要。

例如,给定这个:

@Configuration
public class MyConfig {
    @Bean
    public B example1() {
        return new B();
    }
    @Bean
    public B example2() {
        return new B();
    }
}

好吧,现在您有两个 B 实例,但名称不同。您可以通过以下两种方式之一解决此问题:

验证您的 Autowire

注意我这里使用的是字段注入,你真的应该使用构造函数,我这样做是为了节省空间。

 @Component
public class SomeComponent {

    @Autowired
    @Qualifier("example1")
    private B b;

}

或者

将 Bean 标记为主要的

重新定义bean,将一个标记为@Primary

@Configuration
public class MyConfig {
    @Bean
    @Primary // <-------- NEW!
    public B example1() {
        return new B();
    }
    @Bean
    public B example2() {
        return new B();
    }
}

然后注入,无需命名:

 @Component
public class SomeComponent {

    @Autowired  // (Will pick Primary)
    private B b;

}

【讨论】:

    猜你喜欢
    • 2019-11-15
    • 2017-04-11
    • 2020-09-01
    • 2016-12-05
    • 2018-07-04
    • 2011-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多