一、IOC:控制反转与依赖注入
IOC 把对象的创建和依赖关系交给容器管理,开发者只声明”要什么”,容器负责装配。依赖注入三种方式:
| 方式 | 特点 |
|---|---|
| 构造器注入 | 不可变、必填,推荐 |
| setter 注入 | 可选、易变 |
| 字段注入 | 简洁但难测试、不推荐 |
二、Bean 作用域与生命周期
- singleton(默认):容器中一个实例;prototype:每次取都新建;还有 request/session 等 Web 作用域;
- 生命周期:实例化 → 属性填充 →
BeanNameAware等回调 →@PostConstruct→ 初始化 → 使用中 →@PreDestroy销毁。
三、循环依赖与三级缓存
Spring 用三级缓存解决单例 setter/字段注入的循环依赖:
一级: singletonObjects 成品 Bean
二级: earlySingletonObjects 早期暴露(已实例化未填充)
三级: singletonFactories 早期工厂(生成代理)
关键点:构造器注入无法解决循环依赖(会直接抛 BeanCurrentlyInCreationException);用 @Lazy 可打破。
四、AOP:面向切面
把日志、事务、鉴权等”横切关注点”抽出来。Spring AOP 基于动态代理:
| 代理方式 | 条件 |
|---|---|
| JDK 动态代理 | 目标实现接口 |
| CGLIB | 无接口或对类代理(生成子类) |
通知类型:@Before @After @Around @AfterReturning @AfterThrowing。事务 @Transactional 本质就是 AOP,注意同类方法内部调用会失效(代理没介入)。
五、答题要点
Spring 面试重”原理 + 边界”:循环依赖为什么三级缓存、AOP 代理选择、事务失效场景——能讲清实现机制比背定义更值钱。