Spring 构造器注入 vs 字段注入

一、核心结论(先背这个)

Spring 推荐构造器注入,而不推荐字段注入,
是因为构造器注入能保证对象在创建完成时依赖已经全部就绪,
而字段注入会让对象在一段时间内处于"不完整状态"。


二、两种注入方式的本质区别

1️⃣ 构造器注入(Constructor Injection)

java 复制代码
@Service
public class OrderService {

    private final OrderRepository orderRepository;

    public OrderService(OrderRepository orderRepository) {
        this.orderRepository = orderRepository;
    }
}

本质:

  • 依赖作为构造器参数
  • 没有依赖就无法创建对象
  • 依赖在 new 之前就必须准备好

创建顺序(类比"深度优先"):

text 复制代码
创建 A
 → 先创建 B
   → 再创建 C
 → 再创建 A

2️⃣ 字段注入(Field Injection)

java 复制代码
@Service
public class OrderService {

    @Autowired
    private OrderRepository orderRepository;
}

本质:

  • new 一个"空壳对象"
  • 再通过反射把依赖"塞进去"

创建顺序:

text 复制代码
new OrderService()   ← 依赖此时是 null
↓
反射注入 orderRepository

三、字段注入真实会出错的原因

❌ 出错根源(不是 Spring 的问题)

对象在依赖注入完成之前就已经存在,并且可能被使用


❌ 典型错误示例

java 复制代码
@Service
public class ReportService {

    @Autowired
    private UserRepository userRepository;

    public ReportService() {
        // 此时 userRepository 还没注入
        userRepository.findAll(); // 💥 NPE
    }
}

原因:

  • 构造器执行时,字段注入尚未发生
  • 依赖是 null

✅ 构造器注入不会有这个问题

java 复制代码
public ReportService(UserRepository userRepository) {
    this.userRepository = userRepository;
    userRepository.findAll(); // 一定安全
}

四、设计层面的差异(面试加分点)

字段注入的问题

  • 依赖关系 隐藏
  • 无法使用 final
  • 不利于单元测试
  • 容易掩盖设计问题(依赖过多)

构造器注入的优势

  • 依赖关系 一眼可见
  • 支持 final(不可变)
  • 创建即完整
  • 更容易测试
  • 循环依赖会更早暴露

五、你提出的"深度优先"理解(标准化表述)

构造器注入在 Bean 创建阶段会先解析并实例化其构造器参数,

形成一种类似 深度优先 的依赖构建过程,

从而保证对象在创建完成后依赖已经全部注入完成。

而字段注入是在对象实例化之后再进行依赖填充,

对象在此期间可能处于不完整状态。


六、30 秒面试速记版(终极版)

构造器注入是在对象创建时通过构造方法一次性注入依赖,

可以保证对象创建完成后就是可用状态;

字段注入是先创建对象再通过反射注入依赖,

对象可能短暂处于不完整状态,因此 Spring 官方更推荐构造器注入。

相关推荐
leobertlan30 分钟前
2025年终总结
前端·后端·程序员
面向Google编程1 小时前
从零学习Kafka:数据存储
后端·kafka
易安说AI2 小时前
Claude Opus 4.6 凌晨发布,我体验了一整晚,说说真实感受。
后端
易安说AI2 小时前
Ralph Loop 让Claude无止尽干活的牛马...
前端·后端
易安说AI2 小时前
用 Claude Code 远程分析生产日志,追踪 Claude Max 账户被封原因
后端
JH30732 小时前
SpringBoot 优雅处理金额格式化:拦截器+自定义注解方案
java·spring boot·spring
颜酱3 小时前
图结构完全解析:从基础概念到遍历实现
javascript·后端·算法
Coder_Boy_3 小时前
技术让开发更轻松的底层矛盾
java·大数据·数据库·人工智能·深度学习
invicinble4 小时前
对tomcat的提供的功能与底层拓扑结构与实现机制的理解
java·tomcat
较真的菜鸟4 小时前
使用ASM和agent监控属性变化
java