Spring 的注入方式有哪些?该如何选择?

开发
本文,我们分析了 Spring 的四种注入方式,在选择依赖注入方式时,我们应该根据具体情况和项目来决定。

作为 Java程序员都知道,没有依赖注入,Spring 框架就是无法实现的,那么,在 Spring 框架中,常见的依赖注入方式有哪些呢?我们该如何选择?这篇文章来聊一聊。

从整体上来看,Spring 的依赖注入有四种方式:

  • 构造器注入
  • setter 方法注入
  • 字段注入
  • 接口注入

下面,我们将分别分析它们的原理,以及它们的优缺点。

1. 构造器注入

构造器注入(Constructor Injection)是指通过构造函数传入依赖的对象。Spring 容器在创建 bean 时会调用它的构造函数,并将所需的依赖项作为参数传入。

如下示例展示如何通过构造器注入 bean。

public class Service {
   private final Repository repository;
   public MyService(Repository repository) {
       this.repository = repository;
   }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

优点:

  • 强制性依赖性:在对象创建时,所有必要的依赖项都必须提供,减少了在运行时出现空指针的风险。
  • 不可变性:被注入的依赖可以声明为 final,使得一旦初始化后对象的状态不可更改,从而增强了对象的安全性。
  • 便于单元测试:构造器参数很容易模拟(mock)或替代,方便测试。

缺点:

  • 复杂性:如果一个类有很多依赖,则构造函数可能变得非常复杂,导致可读性差。
  • 潜在的构造函数过载:当添加新的依赖时,可能需要重载多个构造函数,增加了维护成本。

构造器注入是工作中比较推荐的一种方式,因为它编译期行为,可以减少空指针。但是,如果一个类需要很多依赖,构造器注入会导致代码比较臃肿。

2. Setter 注入

Setter 注入(Setter Injection)是指通过 setter 方法注入依赖的对象。Spring 在创建 bean 后,通过调用 setter 方法来设置依赖项。

如下示例展示如何通过 Setter注入 bean。

public class Service {
   private Repository repository;

   public void setMyRepository(Repository repository) {
       this.repository = repository;
   }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

优点:

  • 灵活性:可以选择性地注入依赖项,允许在对象创建后进行注入,适合可选的依赖。
  • 清晰的配置:可以通过 setter 方法明确地配置并查看依赖关系。

缺点:

  • 非强制性依赖:在对象创建后如果没有设置必需的依赖,可能导致运行时的空指针异常。
  • 可变性:依赖可以在对象生命周期内被更改,可能导致不一致的状态。

3. 接口注入

接口注入(Interface Injection)是一个较少使用的方式,通过一个接口将依赖注入到类中。通常实现这个接口的类会提供注入的具体实现。

如下示例展示如何通过接口注入 bean。

public interface DependencyInjector {
   void inject(Service service);
}
  • 1.
  • 2.
  • 3.

优点:

  • 灵活性:可以根据不同的实现提供不同的注入方式。
  • 清晰性:接口明确了所需要的依赖,增强了代码的可理解性。

缺点:

  • 实现复杂性:需要定义额外的接口,增加了复杂性和维护成本。
  • 使用频率低:由于实现复杂,通常不被广泛采用。

4. 字段注入

字段注入(Field Injection)是直接将依赖注入到类的字段中,通常使用反射和注解。通常会 使用 Spring 提供的注解(如 @Autowired, @Inject, @Resource)。这种方式较为简洁,但是会有 NPE的风险。

如下示例展示如何通过字段注入 bean。

public class Service {
   @Autowired
   private Repository repository;
}
  • 1.
  • 2.
  • 3.
  • 4.

优点:

  • 简洁性:代码量较少,使用反射和注解可自动完成依赖注入,易于理解。
  • 方便快捷:无需编写构造函数或 setter 方法。

缺点:

  • 不易于测试:由于字段是私有的,通常不容易替换依赖项进行测试。
  • 依赖性不明显:依赖关系并不明确,影响代码的可读性和维护性。
  • 不支持不可变性:不能将字段声明为 final,这可能导致不一致的状态。

5. 总结

本文,我们分析了 Spring的 4种注入方式,在选择依赖注入方式时,我们应该根据具体情况和项目来决定。根据工作经验,建议如下:

  • 构造器注入是最推荐的方式,特别是在需要强制性依赖和不可变性的场景下。
  • 如果无法通过构造器注入,再选择 setter注入。
  • 如果上述两者方式都不适用,字段注入则是最后的选择,虽然使用简单,但是容易产生NPE。
责任编辑:赵宁宁 来源: 猿java
相关推荐

2020-10-21 10:30:24

deletetruncatedrop

2024-09-12 16:52:38

2023-03-30 16:18:00

智能PDU数据中心

2022-09-27 12:01:56

Spring异步调用方式

2012-07-17 09:16:16

SpringSSH

2024-12-23 15:58:38

2023-06-02 20:36:58

云计算

2023-04-26 14:12:09

光纤数据中心

2024-08-26 15:31:55

2025-03-28 08:10:00

Spring自动装配Java

2020-03-06 08:33:49

开源协议开源软件

2015-07-22 17:30:14

应用交付 太一星晨

2022-09-28 14:54:07

Spring注解方式线程池

2021-08-06 09:43:18

云计算容器云原生

2010-09-14 16:28:52

2021-10-26 00:01:59

Spring方式代码

2011-06-03 11:53:06

Spring接口

2009-09-08 15:22:20

Spring依赖注入

2016-01-06 15:00:49

点赞
收藏

51CTO技术栈公众号