Spring依赖注入的方式一共有三种
- 属性注入
常用的@Autowired spring已经不推荐这种方式
@Autowired
private A a;
- seter注入
private B b;
@Autowired
public void sertB(B b){
this.b = b;
}
- 构造函数注入(推荐)
@Service
class Clazz{
private final C c;
public Clazz(C c){
this.c=c;
}
}
减少模版代码
seter注入和构造函数注入的方式需要写大量的setter或者构造函数,这个时候我们可以使用Lombok @RequiredArgsConstructor 注解自动生成构造函数来实现自动注入
@RequiredArgsConstructor 可以为final没有默认值或有@notNull注解的属性生成全参构造函数
@Component("b")
public class B{
public String getA(){
return "123";
}
}
@Service
@RestController
@RequiredArgsConstructor
public class A {
private final B b;
private final String a= "1";
private final Integer aa= 1;
@RequestMapping("/")
public String getA(){
return b.getA();
}
}
这个时候我们看lombok会为我们生成这样的构造函数
public A(B b) {
this.b = b;
}
一个接口存在多个bean的情况
我们往常在解决一个接口多个bean的时候一般都是这样处理的
@Autowired
@Qualifier("bb")
private final B b;
于是我们简单的在上面的代码做些改造也许可以
@Component("bb")
public class B implements I{
public String getA(){
return "123";
}
}
@Component("cc")
public class C implements I{
public String getA(){
return "123";
}
}
@Service
@RestController
@RequiredArgsConstructor
public class A {
@Qualifier("bb")
private final B b;
private final String a= "1";
private final Integer aa= 1;
@RequestMapping("/")
public String getA(){
return b.getA();
}
}
这个时候我们会看到idea会警告我们这个问题,这个上面说lombok不会复制@Qualifier这个注解到构造函数上,也就是说这个注解是无效的。
这个时候有两个解决方法
- 将属性的名称换成bean的名称
private final I b; -> private final I bb;
这个样子spring就可以通过属性名称识别应该用哪个bean了
2. 配置lombok使其能够复制注解
在项目的根目录创建一个lombok.config文件,如图所示
在文件中配置这些
lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier
lombok.copyableAnnotations += org.springframework.context.annotation.Lazy
lombok.copyableAnnotations配置会将配置的注解 从属性上复制到构造函数上
配置完这个之后,我们回到代码处,现在已经没有警告了.我们看一下字节码,@Qualifier被正常的复制到构造函数上了
@Service
@RestController
public class A {
@Qualifier("bb")
private final I b;
private final String a = "1";
private final Integer aa = 1;
@RequestMapping({"/"})
public String getA() {
return this.b.getA();
}
public A(@Qualifier("bb") I b) {
this.b = b;
}
}