Spring 依赖注入方式主要有 2 种,一是通过 @Autowire
、@Resource
等注解注入,二是通过构造器的方式进行依赖注入。除此之外,其实 lombok 的 @RequiredArgsConstructor
注解也可以完成 spring 的依赖注入,且更简便,更灵活。
@Autowire、@Resource 等注入方式
目前使用最广泛的是 @Autowired
、@Resource
注入方式:
@Service
public class KnowledgeDictServiceImpl implements KnowledgeDictService {
@Autowired
private PushService pushService;
@Resource
private AdminService adminService;
}
显性构造器注入
spring 通过显性构造器注入依赖,示例如下:
@Service
public class KnowledgeDictServiceImpl implements KnowledgeDictService {
private final PushService pushService;
private final AdminService adminService;
public KnowledgeDictServiceImpl(PushService pushService, AdminService adminService) {
this.pushService = pushService;
this.adminService = adminService;
}
}
@RequiredArgsConstructor 注入
@RequiredArgsConstructor
注解可以更简洁地实现构造器的注入,无需显性定义,示例如下:
@Service
@RequiredArgsConstructor
public class KnowledgeDictServiceImpl implements KnowledgeDictService {
final PushService pushService;
final AdminService adminService;
}
如果需要注入的类有多个实现,需要用 @Qualifier
注解指定要注入的 bean 实现,如 PushService
有两个实现 bean,一个 bean name 是 "pushServiceV1"
,另一个是 "pushServiceV2"
,假设要注入 "pushServiceV2"
,示例如下:
@Service
@RequiredArgsConstructor
public class KnowledgeDictServiceImpl implements KnowledgeDictService {
@Qualifier("pushServiceV1")
final PushService pushService;
final AdminService adminService;
}
从显性构造器注入和
@RequiredArgsConstructor
对比可看出,其实它们和 lombok 的@NoArgsConstructor
和@AllArgsConstructor
注解设计是一脉相承的;
@RequiredArgsConstructor
本质上是为每个需要特殊处理的字段生成一个带有 1 个参数的构造函数。所有未初始化的 final 字段都获得一个参数,或标有@NonNull
注解且未初始化的字段也会从构造函数获得一个参数;参数的顺序与字段在类中出现的顺序一致。
@NoArgsConstructor
顾名思义是生成一个没有参数的构造函数,如果有未初始化的final
字段,会导致编译错误。
@AllArgsConstructor
则是为类中的每个字段生成一个带有 1 个参数的构造函数,常用在 pojo 类上。