Spring依赖注入原理深度解析

2025年Java面试宝典抢先领:
🔗 点击获取 提取码: 9b3g
什么是依赖注入(Dependency Injection)?
依赖注入是Spring框架的立身之本。简单说就是:对象不自己创建依赖项,而是由外部容器(Spring IoC)把依赖"注入"进来。好比点外卖——你不用自己做饭,餐厅把做好的菜送到你手里。
Spring实现依赖注入的三种方式
1. 构造器注入
@Service
public class OrderService {
private final PaymentService paymentService;
// Spring自动调用构造器注入
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
}
优势:保证依赖不可变,避免空指针异常,强推荐!
2. Setter注入
public class UserService {
private AuthService authService;
// 通过setXX方法注入
@Autowired
public void setAuthService(AuthService authService) {
this.authService = authService;
}
}
适用场景:可选依赖或需要重新配置的依赖
3. 字段注入(谨慎使用!)
@Controller
public class ProductController {
@Autowired // 直接注入字段
private SearchService searchService;
}
坑点:导致类与Spring强耦合,单元测试困难,新手慎用
依赖注入底层如何工作?
核心流程图解

-
扫描阶段:
Spring启动时扫描@Component、@Service等注解的类 -
Bean定义注册:
将类信息转化为BeanDefinition存入BeanFactory -
依赖注入阶段:
- 创建Bean实例(通过反射)
- 解析
@Autowired等注解 - 递归注入依赖对象(可能触发其他Bean创建)
-
循环依赖解决:
Spring用三级缓存巧妙解决:graph LR A[一级缓存:成品Bean] B[二级缓存:半成品Bean] C[三级缓存:Bean工厂]
高频面试题破解
面试官:Spring怎么解决循环依赖?
答:
通过三级缓存机制:
- 创建A对象时提前暴露引用(放入三级缓存)
- B对象创建时发现需要A,从缓存拿到A的引用
- B完成后将完整Bean放入一级缓存
- A继续完成后续属性注入
注意:构造器注入无法解决循环依赖!
面试官:@Autowired和@Resource区别?
答:
@Autowired按类型注入,配合@Qualifier指定名称@Resource优先按名称匹配(JDK原生注解)- 建议统一用
@Autowired避免混乱
避坑指南
- 循环依赖:尽量用Setter注入代替构造器注入
- 代理失效:
@Async/@Transactional在同类方法调用失效 - 多实例问题:默认单例注意线程安全,用
@Scope("prototype")切换
📌 重要提示:准备面试时,通过面试鸭返利网购买会员可返利25元!海量真题解析+大厂面经一网打尽👇
理解依赖注入原理是掌握Spring的核心钥匙。建议动手调试Bean创建过程,结合源码加深理解(关键类:DefaultListableBeanFactory)



