【问题标题】:Autowiring of beans in spring boot with @Qualifier annotation使用 @Qualifier 注释在 Spring Boot 中自动装配 bean
【发布时间】:2019-07-23 08:32:21
【问题描述】:

我正在使用 @Primary 和 @Qualifier 注释在 Spring Boot 中学习自动装配。我能够理解 @Primary 将带注释的类作为依赖项连接,如果找到多个令人满意的类,@Qualifier 可以提供帮助。

@Component
public class VehicleBean {

    @Autowired
    @Qualifier("car")
    Vehicle car;

    public void check() {
        car.details();
    }
    
    public Vehicle getCar() {
        return car;
    }
    
    public void setCar(Vehicle car) {
        this.car = car;
    }
    
}

自行车

@Component
//@Primary
@Qualifier("car")
public class Bike implements Vehicle {

    @Override
    public void details() {
        System.out.println("Bike is driving");
    }
    
}

汽车

@Component
//@Primary
@Qualifier("bike")
public class Car implements Vehicle {
    @Override
    public void details() {
        System.out.println("Car is driving");
    }
}

当我将 @Qualifier("car") 添加到名为“bike”的自动连接依赖项上,并在 Car 上添加 @Qualifier("car") 并在 Bike 上添加 @Qualifier("bike"),它会选择 Car。但是,当我在 Bike 和 Car 上交换 @Qualifier(例如 - 在 Car 上的 @Qualifier("bike"),反之亦然)时,它会拿起自行车。此外,当我将@Qualifier 更改为“在我的名为“car”的自动装配依赖项上骑自行车并在 Bike 上使用 @Qualifier("car") 时,它正在选择 Car。我期待选择 Bike。我是什么不见了?

【问题讨论】:

  • 这个问题的一些cmets已经被删除。因此,我重新发布了我的问题-当我在名为“car”的自动装配依赖项上添加 @Qualifier("car") 并在 Bike 上添加 @Qualifier("car") 并在 Car 上添加 @Qualifier("bike") 时,它拿起汽车而不是自行车。为什么?

标签: spring spring-boot


【解决方案1】:

这里限定符注解的使用是错误的,限定符注解是用在一个字段、一个参数或者一个方法上,在authowiring时选择写入候选bean,

此注解可用于字段或参数作为限定符 自动装配时的候选 bean。 (JAVA 文档)

简单来说,您通过名称定义bean,并通过添加@Qualifier 告诉spring 要选择什么名称,在您的示例中,您必须在@Component 中添加bean 名称。

@Component("bike")
public class Bike implements Vehicle {

    @Override
    public void details() {
        System.out.println("Bike is driving");
    }

}

@Component("car")
public class Car implements Vehicle {
    @Override
    public void details() {
        System.out.println("Car is driving");
    }
}

关于您的问题,为什么选择 Car? , 因为如果没有指定 AnnotationBeanNameGenerator 会生成一个默认名称,并且构建的名称是基于类的短名称(第一个字母小写):

如果注解的值不表示 bean 名称,则使用适当的 name 将基于类的短名称构建(带有 第一个字母小写)。例如:

com.xyz.FooServiceImpl -> fooServiceImpl (JAVA DOC)

【讨论】:

  • 这里使用@Qualifier 有什么问题?它按预期适用于其他场景。
  • @Qualifer 对 bean 定义没有任何影响,如 JavaDoc 所述,它仅在自动装配字段或方法参数期间选择 bean 时使用。如果你想命名你的 bean,按照@hasnae 的建议进行操作,并将名称传递到 @Component 注释中。
  • Mike - 如果我有 @Qualifier("bike) 在 Car 和 @Qualifier("car") 在 Bike Classes 上没有在 @Component 定义的名称,当我用 @Qualifier("汽车”),它正在选择自行车。当我将@Qualifier(“汽车”)更改为@Qualifier(“自行车”)时,它仍然选择自行车为什么?这是我需要了解的。我无法联系起来实际上是后者,当我将预选赛改为自行车时,我期待它选择 Car,因为 Class 已经用自行车进行了注释。
  • 正如我最后提到的,如果没有定义名称,spring 会生成一个默认名称,在你的情况下,它是 car 用于 Car 类,bike 用于 Bike 类。正如迈克所说,@Qualifier 对班级级别没有影响,您可以省略它
【解决方案2】:

@Qualifier 注释在 @Component @Qualifier("car") 中不起作用。它可以用于自动装配的字段、参数或方法。
您只需传递带有@Component 注释的名称,例如@Component("car")

【讨论】:

  • @Qualifier 确实在类级别上工作。请参阅 spring 文档中的第 7.10.8 节 - docs.spring.io/spring/docs/4.3.12.RELEASE/… 当依靠类路径扫描来自动检测组件时,您可以在候选类上提供带有类型级别注释的限定符元数据
猜你喜欢
  • 2014-06-30
  • 2017-05-04
  • 2012-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-27
  • 1970-01-01
  • 2020-03-21
相关资源
最近更新 更多