三种依赖注入详解

在 Spring 框架中,将一个 Bean 注入到另一个 Bean 里,主要有三种方式。


1. 属性注入 (Field Injection)

这是初学阶段和各种教程中最常见的方式。直接在成员变量上加 @Autowired。

代码示例:

Java

typescript 复制代码
@RestController
public class UserController {

    @Autowired // 核心动作:直接在属性上点名
    private UserService userService;

    public void list() {
        userService.findAll();
    }
}
  • 优点:代码最简洁,看起来非常干净。

  • 缺点:

    • 难以脱离容器使用 :如果你想在没有 Spring 环境的情况下(比如写纯 Java 的单元测试)手动 new 这个对象,你没法给 userService 赋值。
    • 容易循环依赖:如果 A 注入 B,B 又注入 A,这种方式有时会掩盖代码设计的缺陷。

2. Setter 方法注入 (Setter Injection)

通过类的 Setter 方法来完成注入。

代码示例:

Java

typescript 复制代码
@RestController
public class UserController {

    private UserService userService;

    @Autowired // 核心动作:在 Setter 方法上点名
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public void list() {
        userService.findAll();
    }
}
  • 优点:比较灵活,可以在对象创建后重新修改注入的实例。

  • 缺点:

    • 安全性较低:对象在被调用时,可能还没有被注入(比如有人不小心改了值),导致空指针异常。
    • 代码冗长:每个属性都要写一套 Setter。

3. 构造器注入 (Constructor Injection) ------ 官方推荐

通过类的构造方法来完成注入。这是 Spring 官方目前最推荐的方式。

代码示例:

Java

java 复制代码
@RestController
public class UserController {

    private final UserService userService; // 甚至可以加 final,保证不可变

    // 核心动作:在构造函数上注入(Spring 4.3后,如果只有一个构造函数,@Autowired可省略)
    public UserController(UserService userService) {
        this.userService = userService;
    }

    public void list() {
        userService.findAll();
    }
}
  • 优点:

    1. 保证不为空:对象一出生(构造时)就必须把依赖传进来,否则编译报错。
    2. 不可变性 :可以使用 final 关键字,防止以后被修改。
    3. 利于测试 :即便没有 Spring,你也可以轻松地通过 new UserController(mockService) 来进行测试。
  • 缺点:当依赖非常多(比如有 10 个)时,构造函数的参数列表会非常长。


总结:面试怎么答?

方式 推荐程度 理由
构造器注入 ⭐⭐⭐⭐⭐ 官方推荐,安全、可靠、方便测试,保证对象状态完整。
属性注入 ⭐⭐⭐ 开发快,代码省事,但在大型项目和严格测试中不推荐。
Setter 注入 ⭐⭐ 除非需要在运行期间动态改变依赖,否则很少使用。

相关推荐
别动我齐刘海3 小时前
C++ 工程化学习
java·linux·前端·c++·学习·机器学习·机器人
code2cat4 小时前
Java进阶篇之AtomicLongFieldUpdater:把累计额度留在对象字段中
java·cas·并发编程
WeiXin_DZbishe4 小时前
基于springboot城市公交实时运营与调度系统-计算机毕设 附源码【课程设计】66173
java·vue.js·spring boot·后端·python·php·课程设计
泡茶喝茶写代码4 小时前
A股量化数据工程:从 REST 接口到策略信号(第 18 篇):放量缩量异动扫描
java·python·股票数据api·股票数据api接口·股票api数据接口·股票量化数据api·股票量化数据接口
wewowilling4 小时前
认识微服务
java·运维·微服务·springcloud
代码什么用5 小时前
Java Web 7-10
java·servlet
蜗牛互联网6 小时前
GPT-6 与 Intelligent UI:从回答到可审计操作的产品迁移
java·人工智能·后端
SL_staff7 小时前
运维救火实录:钉钉考勤API变更引发工资计算异常,我们用JVS-Logic可视化逻辑引擎实现分钟级热修复
java·mysql·全栈
SunnyDays10117 小时前
Java 查找并高亮 Word 文字:精确查找及正则表达式模糊查找
java·查找文字·word 文档·高亮文字·正则匹配查找·模糊查找