标准答案
- 容器创建对象后进行依赖注入,再执行各类初始化处理器和初始化方法。
- 单例 setter 注入的部分循环依赖可能被提前暴露,构造器循环依赖通常无法创建。
- AOP 代理、FactoryBean、作用域和懒加载会改变实际对象边界。
- 循环依赖应优先通过拆分职责、引入事件或调整依赖方向解决,而不是依赖容器技巧。
题目解析
Bean 生命周期包含实例化、依赖注入、后处理、初始化和销毁。循环依赖能否被提前暴露取决于单例、setter/字段注入、构造器、代理和 Spring 版本,能启动不代表设计合理。
代理可能在初始化后包裹目标对象,FactoryBean、懒加载和不同作用域也会改变实际对象边界。排查资源泄漏时要看代理、目标和容器销毁回调是否都执行。
优先通过拆分职责、调整依赖方向或事件解耦解决循环依赖;依赖容器的提前引用可能隐藏初始化顺序和事务/AOP 失效问题。
常见误区
- 误区:认为所有循环依赖都能自动解决。改正:区分构造器和 setter/字段循环,并优先重构依赖图。
- 误区:把代理对象和目标对象当成同一个生命周期。改正:确认实际 Bean、后处理器和销毁回调的边界。
- 误区:关闭时没有释放线程池和连接。改正:注册资源销毁逻辑,并用优雅停机验证回调真的执行。