Spring @Autowired 和 @Qualifier [关闭]

Posted

技术标签:

【中文标题】Spring @Autowired 和 @Qualifier [关闭]【英文标题】:Spring @Autowired and @Qualifier [closed] 【发布时间】:2022-01-24 03:41:34 【问题描述】:

是否使用 @Autowired 自动检测到? 使用@Qualifier时,是否是通过名称进行依赖注入? 我们如何使用这些注解进行 setter 和构造函数注入?

【问题讨论】:

【参考方案1】:

您可以将@Qualifier@Autowired 一起使用。事实上,如果发现不明确的 bean 类型,spring 会要求你明确选择 bean,在这种情况下你应该提供限定符

例如在以下情况下,必须提供限定符

@Component
@Qualifier("staff") 
public Staff implements Person 

@Component
@Qualifier("employee") 
public Manager implements Person 


@Component
public Payroll 

    private Person person;

    @Autowired
    public Payroll(@Qualifier("employee") Person person)
          this.person = person;
    


编辑:

在 Lombok 1.18.4 中,当你有 @Qualifier 时,终于可以避免构造函数注入的样板,所以现在可以执行以下操作:

@Component
@Qualifier("staff") 
public Staff implements Person 

@Component
@Qualifier("employee") 
public Manager implements Person 


@Component
@RequiredArgsConstructor
public Payroll 
   @Qualifier("employee") private final Person person;

如果您使用新的 lombok.config 规则 copyableAnnotations(通过将以下内容放在项目根目录的 lombok.config 中):

# Copy the Qualifier annotation from the instance variables to the constructor
# see https://github.com/rzwitserloot/lombok/issues/745
lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier

这是最近在最新的 lombok 1.18.4 中引入的。

详细讨论该问题的blog post github 上的original issue 还有a small github 项目来看看它的实际效果

注意

如果您使用字段或 setter 注入,则必须将 @Autowired 和 @Qualifier 放在字段或 setter 函数的顶部,如下所示(其中任何一个都可以工作

public Payroll 
   @Autowired @Qualifier("employee") private final Person person;

public Payroll 
   private final Person person;
   @Autowired
   @Qualifier("employee")
   public void setPerson(Person person) 
     this.person = person;
    

如果你使用构造函数注入,那么注释应该放在构造函数上,否则代码将无法工作。像下面这样使用它 -

public Payroll 

    private Person person;

    @Autowired
    public Payroll(@Qualifier("employee") Person person)
          this.person = person;
    


【讨论】:

【参考方案2】:

@Qualifier 注解用于解决自动装配冲突,当有多个相同类型的 bean 时。

@Qualifier 注解可以用在任何用@Component 注解的类或用@Bean 注解的方法上。此注解也可以应用于构造函数参数或方法参数。

例如:-

public interface Vehicle 
     public void start();
     public void stop();

有两个bean,Car和Bike实现Vehicle接口

@Component(value="car")
public class Car implements Vehicle 

     @Override
     public void start() 
           System.out.println("Car started");
     

     @Override
     public void stop() 
           System.out.println("Car stopped");
     
 

@Component(value="bike")
public class Bike implements Vehicle 

     @Override
     public void start() 
          System.out.println("Bike started");
     

     @Override
     public void stop() 
          System.out.println("Bike stopped");
     

使用 @Autowired@Qualifier 注释在 VehicleService 中注入 Bike bean。如果你没有使用@Qualifier,它会抛出NoUniqueBeanDefinitionException

@Component
public class VehicleService 

    @Autowired
    @Qualifier("bike")
    private Vehicle vehicle;

    public void service() 
         vehicle.start();
         vehicle.stop();
    

参考:-@Qualifier annotation example

【讨论】:

【参考方案3】:

@Autowired 按类型自动连接(或搜索)@Qualifier 按名称自动连接(或搜索)@Qualifier 的其他替代选项是 @Primary

@Component
@Qualifier("beanname")
public class A

public class B

//Constructor
@Autowired  
public B(@Qualifier("beanname")A a)... //  you need to add @autowire also 

//property
@Autowired
@Qualifier("beanname")
private A a;



//If you don't want to add the two annotations, we can use @Resource
public class B

//property
@Resource(name="beanname")
private A a;

//Importing properties is very similar
@Value("$property.name")  //@Value know how to interpret $
private String name;

更多关于@value

【讨论】:

以上是关于Spring @Autowired 和 @Qualifier [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Spring 注释 @Autowired 和@Resource 的区别

Spring 注解 @Resource和@Autowired

spring装配之 @Autowired 和 @Resource 注解的区别

[spring]@Resource和@Autowired区别对比

Spring @Autowired 和 @Qualifier [关闭]

Spring @Autowired 和 @Qualifier [关闭]