★ Spring IoC 是什么?Bean 的生命周期经历了哪些阶段?
结论先行:IoC(控制反转)把“对象由谁创建、依赖怎么装配”的控制权从业务代码反转给 Spring 容器;DI(依赖注入)是它的主要实现手段。Bean 生命周期抓住“实例化 → 属性填充 → Aware 回调 → 初始化 → 就绪 → 销毁”主线即可,重点能说出 @PostConstruct、InitializingBean、init-method 的执行顺序,以及 AOP 代理在哪一步介入。
Bean 生命周期主流程
- 解析配置注册 BeanDefinition(类信息、作用域、依赖关系);
- 实例化:推断构造器后反射创建对象,此时只是“半成品”;
- 属性填充:把依赖通过构造器/setter/字段注入进来;
- Aware 回调:BeanNameAware → BeanFactoryAware → ApplicationContextAware;
- BeanPostProcessor#postProcessBeforeInitialization(初始化前置增强);
- 执行初始化:@PostConstruct → InitializingBean#afterPropertiesSet → init-method;
- BeanPostProcessor#postProcessAfterInitialization(AOP 代理通常在此生成);
- 放入单例池对外提供服务;容器关闭时按反序销毁:@PreDestroy → DisposableBean#destroy → destroy-method。
执行顺序验证
@Component
public class DemoBean implements InitializingBean, DisposableBean {
public DemoBean() { System.out.println("1 构造"); }
@Autowired
public void setDep(Dep dep) { System.out.println("2 属性注入"); }
@PostConstruct
public void init() { System.out.println("3 @PostConstruct"); }
@Override
public void afterPropertiesSet() { System.out.println("4 InitializingBean"); }
@PreDestroy
public void pre() { System.out.println("5 @PreDestroy"); }
@Override
public void destroy() { System.out.println("6 DisposableBean"); }
}
输出顺序为 1→2→3→4;容器关闭时为 5→6。
IoC 带来的收益
- 解耦:调用方只依赖类型/接口,替换实现不动业务代码;
- 可测试:测试时容器可注入 mock 依赖;
- 支撑生态:事务、AOP、缓存等注解能力,都建立在“容器统一管理 Bean 与代理”之上。
常见追问 / 记忆点
- 追问:AOP 代理在生命周期的哪一步生效?答:BeanPostProcessor 的 postProcessAfterInitialization 阶段,容器用代理对象替换原始 Bean。
- 追问:三个初始化方法同时配置按什么顺序执行?答:@PostConstruct → afterPropertiesSet → init-method,销毁顺序正好相反。
- 记忆点:主链“构造→注入→Aware→BPP→初始化→销毁”;Aware 与 BeanPostProcessor 是两个主要扩展点。