在 Spring 中,依赖注入(Dependency Injection, DI)是实现控制反转(IoC)的核心机制,常用的依赖注入方式有两种:Setter 注入 和 构造器注入。
Setter注入:
Setter 注入是通过调用 Bean 的 Setter 方法来完成依赖注入的。Spring 容器在创建 Bean 后,会调用相应的 Setter 方法将依赖的 Bean 注入到目标 Bean 中。
代码示例:
@Component
public class BeanA {
private BeanB beanB;
@Autowired
public void setBeanB(BeanB beanB) { // Setter 方法
this.beanB = beanB;
}
}
特点:
- 灵活性:可以在 Bean 创建后动态地注入依赖。
- 可选性:依赖是可选的,即使不注入也不会导致 Bean 创建失败。
- 顺序性:依赖注入的顺序由 Spring 容器决定,而不是由代码逻辑决定。
2. 构造器注入
构造器注入是通过调用 Bean 的构造函数来完成依赖注入的。Spring 容器在创建 Bean 时,会通过构造函数将依赖的 Bean 注入到目标 Bean 中。
示例代码:
@Component
public class BeanA {
private final BeanB beanB;
@Autowired
public BeanA(BeanB beanB) { // 构造函数
this.beanB = beanB;
}
}
特点:
- 不可变性:依赖通常是
final
的,确保了依赖在 Bean 生命周期内不可变。 - 强制性:依赖是强制的,如果依赖无法注入,Bean 创建会失败。
- 明确性:依赖关系在构造函数中明确声明,便于理解和维护。
主要区别:
特性 | Setter注入 | 构造器注入 |
依赖的可变性 | 依赖可以动态修改 | 依赖通常是fianl 不可修改 |
依赖的强制性 | 可选,可以不注入 | 强制的,必须注入 |
代码可读性 | 依赖关系分散在多个Setter方法中 | 依赖关系集中在构造函数中,更清晰 |
循环依赖问题 | 通过三级缓存解决 | 通过@Lazy注解解决 |
总结
- Setter 注入:灵活、可选,适合动态修改依赖的场景。
- 构造器注入:强制、不可变,适合大多数场景,是 Spring 官方推荐的方式。
- 强制依赖使用构造器注入,使用Setter注入有概率不进行注入导致null对象出现。
- 可先依赖使用setter注入,灵活性强。
- pring 官方推荐构造器注入。第三方框架内部大多使用构造器注入的形式进行数据初始化,相对严谨。
- 自己开发的模块推荐使用Setter注入