依赖注入(DI)是Spring容器生命周期中“属性填充”阶段的具体执行环节,发生在Bean实例化之后、初始化之前,由容器按依赖拓扑顺序统一完成,支持循环依赖与多作用域动态注入。

依赖注入(DI)本身是 Spring 容器生命周期管理的“执行环节”,不是独立过程。真正起作用的是容器——它在启动、运行、关闭的每个阶段,按固定顺序调度 Bean 的创建、装配与销毁。脱离容器谈 DI,就像只讲“送快递”却不提物流中心和运输路线。
容器启动时:DI 的准备阶段
Spring 不是在你写 @Autowired 的那一刻就去注入,而是在容器启动过程中统一处理:
- 先扫描所有配置(
@Component、@Bean、XML),生成BeanDefinition并注册进beanDefinitionMap - 再按依赖关系排序(拓扑排序),确保 A 依赖 B 时,B 先于 A 实例化
- 此时只是“记下谁要注入谁”,还没真正赋值
Bean 实例化后:DI 的实际发生点
DI 发生在实例化之后、初始化之前,属于生命周期中明确的“属性填充(Populate)”阶段:
- 对象已通过构造器或工厂方法创建出来,但字段还是 null
- 容器根据
BeanDefinition中记录的依赖项,把对应 Bean 或值填入字段、构造参数或 Setter 方法 - 这个过程支持循环依赖(仅限 singleton + setter/field 注入),靠三级缓存实现,不是靠“猜顺序”
容器运行期:DI 的持续保障
DI 不是一次性动作,而是由容器全程维系的上下文关系:
- 每次调用
getBean()获取 prototype Bean,都会触发全新一轮 DI 流程 - Web 场景中,request/session 作用域 Bean 在每次请求开始时重建并重新注入
- AOP 代理(如
@Transactional)是在 DI 完成、初始化之后才生成的,所以注入的对象其实是代理后的实例
容器关闭时:DI 关系的自然终结
DI 的终点取决于容器是否还持有引用:
- singleton Bean 的依赖链随容器关闭而整体失效,但不会主动“反向注入”或清理对方
- prototype Bean 不归容器管理销毁,它的依赖对象即使被注入,也不会因容器关闭而自动释放——这点常被忽略,容易导致内存泄漏
- 若某 Bean 在销毁前需通知其依赖项(比如断开连接),必须显式实现
@PreDestroy或DisposableBean,不能指望 DI 自动倒推


















