DI(Dependency Injection)是实现 IoC 的具体手段,是通过容器将依赖关系注入到对象中。
构造函数注入
在类的构造方法上使用@Autowired:
private final PaymentService paymentService;
// Spring 4.3+ 自动识别单构造方法
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
特点:
- 强制依赖:确保对象创建时所有必要依赖已注入,避免
NullPointerException。 - 不可变性:依赖字段可声明为
final,保障线程安全。 - 循环依赖检测:若存在循环依赖,启动时会直接报错(优于字段注入的运行时异常)。
- 推荐场景:核心必选依赖、需要不可变对象的场景。
Setter 方法注入
在 Setter 方法上标注@Autowired:
private UserRepository userRepository;
@Autowired(required = true) // 如果未被正确注入依赖 会抛出 BeanInitializationException
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
特点:
- 可选依赖:允许依赖在对象创建后动态注入(如重新配置)。
- 灵活性:可通过多次调用修改依赖(慎用,可能破坏状态)。
- 显式空值检查:若依赖未找到会抛出异常,但发生在调用时而非启动时。
- 推荐场景:可选依赖或需要动态重新配置的场景。
字段注入
直接在字段上使用@Autowired:
@Autowired
private ProductRepository productRepository;
- 潜在问题:
- 破坏封装性(字段私有但被 Spring 反射修改)。
- 无法声明
final,对象状态可变。 - 单元测试需依赖 Spring 容器或反射工具。
- 不推荐场景:生产环境核心代码,尤其是需要测试或维护性高的项目。
@Resource
@Resource 是 JSR-250 标准注解,Spring 对其提供了支持 。 它按名称(by name)注入依赖,与 @Autowired 按类型(by type)注入的机制不同。
- 按名称注入:
@Resource(name = "mysqlProductRepository") private ProductRepository productRepository; - 默认行为:
@Resource // 默认按字段名 productRepository 查找 Bean private ProductRepository productRepository;
构造函数注入
在类的构造方法上使用@Autowired:
private final PaymentService paymentService;
// Spring 4.3+ 自动识别单构造方法
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
特点:
- 强制依赖:确保对象创建时所有必要依赖已注入,避免
NullPointerException。 - 不可变性:依赖字段可声明为
final,保障线程安全。 - 循环依赖检测:若存在循环依赖,启动时会直接报错(优于字段注入的运行时异常)。
- 推荐场景:核心必选依赖、需要不可变对象的场景。
Setter 方法注入
在 Setter 方法上标注@Autowired:
private UserRepository userRepository;
@Autowired(required = true) // 如果未被正确注入依赖 会抛出 BeanInitializationException
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
特点:
- 可选依赖:允许依赖在对象创建后动态注入(如重新配置)。
- 灵活性:可通过多次调用修改依赖(慎用,可能破坏状态)。
- 显式空值检查:若依赖未找到会抛出异常,但发生在调用时而非启动时。
- 推荐场景:可选依赖或需要动态重新配置的场景。
字段注入
直接在字段上使用@Autowired:
@Autowired
private ProductRepository productRepository;
- 潜在问题:
- 破坏封装性(字段私有但被 Spring 反射修改)。
- 无法声明
final,对象状态可变。 - 单元测试需依赖 Spring 容器或反射工具。
- 不推荐场景:生产环境核心代码,尤其是需要测试或维护性高的项目。
@Resource
@Resource 是 JSR-250 标准注解,Spring 对其提供了支持 。 它按名称(by name)注入依赖,与 @Autowired 按类型(by type)注入的机制不同。
- 按名称注入:
@Resource(name = "mysqlProductRepository") private ProductRepository productRepository; - 默认行为:
@Resource // 默认按字段名 productRepository 查找 Bean private ProductRepository productRepository;
构造函数注入
在类的构造方法上使用@Autowired:
private final PaymentService paymentService;
// Spring 4.3+ 自动识别单构造方法
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
特点:
- 强制依赖:确保对象创建时所有必要依赖已注入,避免
NullPointerException。 - 不可变性:依赖字段可声明为
final,保障线程安全。 - 循环依赖检测:若存在循环依赖,启动时会直接报错(优于字段注入的运行时异常)。
- 推荐场景:核心必选依赖、需要不可变对象的场景。
Setter 方法注入
在 Setter 方法上标注@Autowired:
private UserRepository userRepository;
@Autowired(required = true) // 如果未被正确注入依赖 会抛出 BeanInitializationException
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
特点:
- 可选依赖:允许依赖在对象创建后动态注入(如重新配置)。
- 灵活性:可通过多次调用修改依赖(慎用,可能破坏状态)。
- 显式空值检查:若依赖未找到会抛出异常,但发生在调用时而非启动时。
- 推荐场景:可选依赖或需要动态重新配置的场景。
字段注入
直接在字段上使用@Autowired:
@Autowired
private ProductRepository productRepository;
- 潜在问题:
- 破坏封装性(字段私有但被 Spring 反射修改)。
- 无法声明
final,对象状态可变。 - 单元测试需依赖 Spring 容器或反射工具。
- 不推荐场景:生产环境核心代码,尤其是需要测试或维护性高的项目。
@Resource
@Resource 是 JSR-250 标准注解,Spring 对其提供了支持 。 它按名称(by name)注入依赖,与 @Autowired 按类型(by type)注入的机制不同。
- 按名称注入:
@Resource(name = "mysqlProductRepository") private ProductRepository productRepository; - 默认行为:
@Resource // 默认按字段名 productRepository 查找 Bean private ProductRepository productRepository;
构造函数注入
在类的构造方法上使用@Autowired:
private final PaymentService paymentService;
// Spring 4.3+ 自动识别单构造方法
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
特点:
- 强制依赖:确保对象创建时所有必要依赖已注入,避免
NullPointerException。 - 不可变性:依赖字段可声明为
final,保障线程安全。 - 循环依赖检测:若存在循环依赖,启动时会直接报错(优于字段注入的运行时异常)。
- 推荐场景:核心必选依赖、需要不可变对象的场景。
Setter 方法注入
在 Setter 方法上标注@Autowired:
private UserRepository userRepository;
@Autowired(required = true) // 如果未被正确注入依赖 会抛出 BeanInitializationException
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
特点:
- 可选依赖:允许依赖在对象创建后动态注入(如重新配置)。
- 灵活性:可通过多次调用修改依赖(慎用,可能破坏状态)。
- 显式空值检查:若依赖未找到会抛出异常,但发生在调用时而非启动时。
- 推荐场景:可选依赖或需要动态重新配置的场景。
字段注入
直接在字段上使用@Autowired:
@Autowired
private ProductRepository productRepository;
- 潜在问题:
- 破坏封装性(字段私有但被 Spring 反射修改)。
- 无法声明
final,对象状态可变。 - 单元测试需依赖 Spring 容器或反射工具。
- 不推荐场景:生产环境核心代码,尤其是需要测试或维护性高的项目。
@Resource
@Resource 是 JSR-250 标准注解,Spring 对其提供了支持 。 它按名称(by name)注入依赖,与 @Autowired 按类型(by type)注入的机制不同。
- 按名称注入:
@Resource(name = "mysqlProductRepository") private ProductRepository productRepository; - 默认行为:
@Resource // 默认按字段名 productRepository 查找 Bean private ProductRepository productRepository;