Java Spring @Autowired 和 @Qualifier

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40830548/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 22:56:28  来源:igfitidea点击:

Spring @Autowired and @Qualifier

javaspring

提问by Dhananjaya Senanayake

Is it auto detected with @Autowired? Is it dependency injection by name when @Qualifier is used? How can we do setter and constructor injection using these annotations?

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

回答by kuhajeyan

You can use @Qualifieralong with @Autowired. In fact spring will ask you explicitly select the bean if ambiguous bean type are found, in which case you should provide the qualifier

您可以@Qualifier@Autowired. 事实上,如果找到不明确的 bean 类型,spring 会要求您明确选择 bean,在这种情况下,您应该提供限定符

For Example in following case it is necessary provide a qualifier

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

@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;
    }

}

EDIT:

编辑:

In Lombok 1.18.4 it is finally possible to avoid the boilerplate on constructor injection when you have @Qualifier, so now it is possible to do the following:

在 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;
}

provided you are using the new lombok.config rule copyableAnnotations (by placing the following in lombok.config in the root of your project):

如果您使用的是新的 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

This was recently introduced in latest lombok 1.18.4.

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

NOTE

笔记

If you are using field or setter injection then you have to place the @Autowired and @Qualifier on top of the field or setter function like below(any one of them will work)

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

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

or

或者

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

If you are using constructor injection then the annotations should be placed on constructor, else the code would not work. Use it like below -

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

public Payroll {

    private Person person;

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

}

回答by Anil Nivargi

The @Qualifierannotation is used to resolve the autowiring conflict, when there are multiple beans of same type.

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

The @Qualifierannotation can be used on any class annotated with @Componentor on methods annotated with @Bean. This annotation can also be applied on constructor arguments or method parameters.

所述@Qualifier注释可以与注释的任何类使用@Component或与所注解的方法@Bean。此注释也可以应用于构造函数参数或方法参数。

Ex:-

前任:-

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

There are two beans, Car and Bike implements Vehicle interface

有两个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");
     }
}

Injecting Bike bean in VehicleService using @Autowiredwith @Qualifierannotation. If you didn't use @Qualifier, it will throw NoUniqueBeanDefinitionException.

注射自行车豆在VehicleService使用@Autowired@Qualifier注解。如果你没有使用@Qualifier,它会抛出NoUniqueBeanDefinitionException

@Component
public class VehicleService {

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

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

Reference:- @Qualifier annotation example

参考:-@ Qualifier 注释示例

回答by Premraj

@Autowiredto autowire(or search) by-type
@Qualifierto autowire(or search) by-name
Other alternate option for @Qualifieris @Primary

@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;
}

more about @value

更多关于@value