在春季启动时使用@Qualifier注释自动装配bean

时间:2019-07-23 08:32:21

标签: spring spring-boot

我正在学习使用@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。我是什么?失踪了吗?

2 个答案:

答案 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")