Spring依赖注入的三种方式
大家好,今天咱们来聊聊面试常客——Spring依赖注入。作为Java开发者,搞懂Spring的依赖注入机制是基本功。下面我就结合实战经验,掰开揉碎说说这三种核心实现方式,帮你在面试中游刃有余。
福利放送:需要最新Java面试资料的同学,这里有一份【2025年Java面试宝典】:
🔗 百度网盘链接
📁 提取码:9b3g (建议保存备用)
一、字段注入(Field Injection)
这种写法最偷懒,直接在字段上加@Autowired。比如在Service里要注入Dao:
@Service
public class UserService {
@Autowired
private UserDao userDao; // 字段上直接标注
}
特点:
- ✅ 代码量最少,写起来快
- ⚠️ 但隐患最大!容易导致NPE(空指针)
- ⚠️ 破坏封装性,字段必须是public或protected
- ❌ 无法注入final字段
实际面试中,我常被问到:“为什么Spring官方现在不推荐字段注入?” —— 核心答案就是不可控性强、难以维护。

二、Setter注入(Setter Injection)
通过setter方法注入依赖:
@Service
public class OrderService {
private PaymentGateway gateway;
@Autowired
public void setGateway(PaymentGateway gateway) {
this.gateway = gateway;
}
}
核心优势:
- 🔧 支持可选依赖(配合
@Autowired(required=false)) - 🔄 方便动态替换实现(比如测试时Mock对象)
- ⚠️ 但存在对象半初始化风险(setter调用前状态不稳定)
面试官可能会追问:“Setter注入适合什么场景?” —— 我的答案是可选依赖或需要动态配置的场景,比如插件式架构。
三、构造器注入(Constructor Injection)★ 推荐
Spring官方钦定的首选方式:
@Service
public class ProductService {
private final InventoryDao inventoryDao;
private final PriceCalculator calculator;
@Autowired
public ProductService(InventoryDao dao, PriceCalculator calc) {
this.inventoryDao = dao;
this.calculator = calc;
}
}
为什么最靠谱:
- 🛡️ 强制依赖不可变(final字段)
- 💉 保证对象创建时已完成初始化
- 🧪 单元测试更方便(直接传参构造)
- 🚫 避免循环依赖(启动就会报错)

如何选择?场景建议
- 强依赖必选 → 构造器注入
- 可选/动态依赖 → Setter注入
- 快速原型开发 → 字段注入(但生产环境要替换掉)
📣 特别提示:
准备面试的同学如果需要开通面试鸭会员,通过 面试鸭返利网 找我可返25元!海量大厂真题+解析实时更新,助你高效备战⬇️
高频面试题预演
-
Q:三种依赖注入方式线程安全性区别?
→ 构造器注入天然线程安全(final字段),其他两种需额外同步 -
Q:循环依赖场景下哪种注入会失效?
→ 构造器注入直接报错,字段/Setter注入可通过三级缓存解决 -
Q:为什么Spring4.x开始推荐构造器注入?
→ 不可变性、依赖明确、兼容Test框架
最后强调:理解Spring依赖注入不仅是背八股文,更要明白设计思想。掌握好这三种方式,能让你在复杂系统设计中合理管理对象依赖关系。
👨💻 本文首发于 面试鸭返利网,转载需授权
💡 持续关注获取更多面试技术解析与求职攻略



