设计模式

设计模式

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;