我正在学习使用@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");
}
}
当我在名为“ bike”的自动连接依赖项上添加@Qualifier("car")
并在Car上有@Qualifier("car")
并在Bike上有@Qualifier("bike")
时,它将接载Car。但是,当我在Bike and Car上交换@Qualifier
(例如Car上的@Qualifier("bike")
,反之亦然)时,它将拿起自行车。另外,当我将@Qualifier更改为“基于我自动连接的依赖项上的自行车,称为“汽车”,并在Bike和反之亦然上具有@Qualifier(“ car”)时,它选择的是Car。我期望选择的是Bike。我是什么?失踪了吗?
答案 0 :(得分:3)
这里使用限定符注释是不正确的,在字段,参数或方法上使用限定符注释以在认证时选择写入候选Bean,
此注释可以在字段或参数上用作限定符 自动装配时选择候选bean。 (JAVA DOC)
简单来说,您可以通过名称定义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名称,则使用适当的 名称将基于类的短名称(带有 首字母小写)。例如:
com.xyz.FooServiceImpl-> fooServiceImpl(JAVA DOC)
答案 1 :(得分:0)
@Qualifier
注释在此处@Component @Qualifier("car")
不起作用。它可以用于字段,参数或自动装配方法。
您只需传递带有@Component
批注的名称,例如@Component("car")