【发布时间】:2017-04-11 08:43:23
【问题描述】:
是否使用 @Autowired 自动检测到?
使用@Qualifier时,是否是通过名称进行依赖注入?
我们如何使用这些注解进行 setter 和构造函数注入?
【问题讨论】:
是否使用 @Autowired 自动检测到?
使用@Qualifier时,是否是通过名称进行依赖注入?
我们如何使用这些注解进行 setter 和构造函数注入?
【问题讨论】:
您可以将@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 中引入的。
注意
如果您使用字段或 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;
}
}
【讨论】:
@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();
}
}
【讨论】:
@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
【讨论】: