Spring IoC容器深度解析:Bean生命周期与循环依赖三级缓存
一、Bean生命周期全流程
Spring IoC容器中,Bean的生命周期分为四大阶段 (实例化→属性填充→初始化→销毁),每个阶段都提供丰富的扩展点,总计可细分为12个子步骤。
1.1 生命周期流程图
java
// 入口:AbstractBeanFactory.doGetBean()
protected <T> T doGetBean(...) {
// 1. 转换beanName(处理别名、FactoryBean前缀等)
String beanName = transformedBeanName(name);
// 2. 从缓存中获取单例(解决循环依赖的关键)
Object sharedInstance = getSingleton(beanName);
// 3. 缓存未命中,开始创建Bean
return createBean(beanName, mbd, args);
}
完整生命周期:
┌─────────────────────────────────────────────────────────────┐
│ Spring Bean 生命周期(12步) │
├──────────────┬──────────────────┬────────────────────────────┤
│ 阶段 │ 扩展点 │ 说明 │
├──────────────┼──────────────────┼────────────────────────────┤
│ 1. 实例化 │ │ 通过反射/工厂创建Bean实例 │
│ │ │ │
│ 2. 属性填充 │ │ 注入依赖(@Autowired/@Value)│
│ │ │ │
│ 3. 前置处理 │ postProcessBefore│ BeanPostProcessor介入 │
│ │Initialization │ │
│ │ │ │
│ 4. 初始化 │ afterProperties │ InitializingBean.after... │
│ │Set │ │
│ │ │ │
│ 5. 自定义 │ init-method │ XML/@Bean的initMethod属性 │
│ 初始化 │ │ │
│ │ │ │
│ 6. 后置处理 │ postProcessAfter │ AOP代理在此阶段生成 │
│ │Initialization │ │
│ │ │ │
│ 7. 就绪 │ │ Bean可被其他组件使用 │
│ │ │ │
│ 8. 销毁前置 │ │ │
│ │ │ │
│ 9. 销毁 │ destroy-method │ DisposableBean.destroy() │
│ │ │ │
│ 10. 完成 │ │ 等待GC回收 │
└──────────────┴──────────────────┴────────────────────────────┘
1.2 源码级深入解析
阶段1:实例化(Instantiation)
java
// AbstractAutowireCapableBeanFactory.createBeanInstance()
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// 1. 通过Supplier创建(JDK 8+)
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 2. 通过工厂方法创建
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 3. 通过构造函数创建(最常见)
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// 4. 默认无参构造
return instantiateBean(beanName, mbd);
}
// 最终调用:
BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
Object beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
阶段2:属性填充(Populate Properties)
java
// AbstractAutowireCapableBeanFactory.populateBean()
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
// 1. InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
// 可以阻止属性填充(返回false)
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor ibp) {
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return; // 跳过属性填充
}
}
}
}
// 2. 按名称/类型自动注入
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
}
// 3. @Autowired注解处理(最关键)
pvs = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
// 4. 应用PropertyValues到Bean
applyPropertyValues(beanName, mbd, bw, pvs);
}
阶段3:初始化(Initialization)
java
// AbstractAutowireCapableBeanFactory.initializeBean()
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
// 1. 调用Aware接口
invokeAwareMethods(beanName, bean);
// 2. BeanPostProcessor.postProcessBeforeInitialization()
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
// 3. 调用InitializingBean.afterPropertiesSet()
invokeInitMethods(beanName, wrappedBean, mbd);
// 4. 调用init-method
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName))) {
invokeCustomInitMethod(beanName, wrappedBean, mbd);
}
}
// 5. BeanPostProcessor.postProcessAfterInitialization()
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
1.3 扩展点详解
扩展点1:BeanPostProcessor(最常用)
java
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 初始化前调用(属性已填充)
System.out.println("Before init: " + beanName);
return bean; // 可以返回代理对象
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// 初始化后调用(AOP代理在此生成)
System.out.println("After init: " + beanName);
return bean;
}
}
执行顺序测试:
java
@Component
public class UserService implements InitializingBean {
public UserService() {
System.out.println("1. 实例化构造函数");
}
@Autowired
private UserDao userDao;
public void setUserDao(UserDao userDao) {
System.out.println("2. 属性填充(setUserDao)");
this.userDao = userDao;
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("3. InitializingBean.afterPropertiesSet()");
}
@PostConstruct
public void init() {
System.out.println("4. @PostConstruct init()");
}
public void customInit() {
System.out.println("5. XML init-method");
}
@PreDestroy
public void cleanup() {
System.out.println("6. @PreDestroy");
}
}
输出顺序:
1. 实例化构造函数
2. 属性填充(setUserDao)
3. BeanPostProcessor.postProcessBeforeInitialization
4. @PostConstruct init()
4. InitializingBean.afterPropertiesSet()
5. XML init-method
6. BeanPostProcessor.postProcessAfterInitialization
二、循环依赖与三级缓存
2.1 什么是循环依赖
java
// 场景:A依赖B,B依赖A
@Service
public class A {
@Autowired
private B b;
}
@Service
public class B {
@Autowired
private A a;
}
创建过程分析:
- 创建A,实例化后填充属性b
- b未创建,开始创建B
- B实例化后填充属性a
- a正在创建但尚未完成,如何获取?
Spring解决策略 :通过三级缓存提前暴露半成品Bean。
2.2 三级缓存详解
缓存结构 (DefaultSingletonBeanRegistry):
java
public class DefaultSingletonBeanRegistry {
// 一级缓存:完全初始化好的Bean(成品)
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 二级缓存:提前曝光的Bean(半成品,尚未填充属性)
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
// 三级缓存:ObjectFactory,用于生成二级缓存对象
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
// 正在创建的Bean集合(标记作用)
private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
}
三级缓存工作流程(解决循环依赖):
Step 1: 创建A,实例化后暴露ObjectFactory到三级缓存
java
// AbstractBeanFactory.doGetBean() 调用 createBean()
// 在实例化后、填充属性前,调用 addSingletonFactory()
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
// 1. 放入三级缓存
this.singletonFactories.put(beanName, singletonFactory);
// 2. 清除二级缓存(确保从工厂获取最新)
this.earlySingletonObjects.remove(beanName);
// 3. 标记为正在创建
this.registeredSingletons.add(beanName);
}
}
}
// ObjectFactory的实现(暴露半成品A)
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
// getEarlyBeanReference 可能的处理(AOP代理)
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor ibp) {
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
Step 2: A填充属性b,开始创建B
java
populateBean(beanName, mbd, bw) {
// 发现需要注入b
b = getBean("b"); // 触发B的创建
}
Step 3: B实例化后,填充属性a
java
populateBean("b", mbdB, bwB) {
// 发现需要注入a
a = getBean("a"); // 再次获取A
}
Step 4: B获取a时,从三级缓存获取半成品
java
// 再次进入 getSingleton(beanName) 方法
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 1. 先查一级缓存(成品)
Object singletonObject = this.singletonObjects.get(beanName);
// 2. 一级缓存没有,且正在创建中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 3. 查二级缓存(半成品)
singletonObject = this.earlySingletonObjects.get(beanName);
// 4. 二级缓存没有,且允许早期引用
if (singletonObject == null && allowEarlyReference) {
// 5. 从三级缓存获取ObjectFactory
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 6. 调用工厂生成半成品(可能创建代理)
singletonObject = singletonFactory.getObject();
// 7. 提升到二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
// 8. 从三级缓存移除
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
Step 5: B成功填充a,完成初始化,放入一级缓存
java
// B填充完a后,继续初始化流程
initializeBean("b", b, mbdB) {
// ... 初始化步骤 ...
}
// B初始化完成,放入一级缓存
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
Step 6: A成功填充b,完成初始化,放入一级缓存
java
// 回到A的创建流程,此时b已准备就绪
populateBean("a", mbdA, bwA) {
// b已创建完成,直接注入
bwA.setPropertyValues(pvs); // 注入b
}
// 继续初始化,最终放入一级缓存
2.3 三级缓存核心逻辑
为什么需要三级缓存?
二级缓存足够吗?
java
// ❌ 如果只有二级缓存(直接放半成品)
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
// 直接放入二级缓存(问题:AOP代理如何生成?)
this.earlySingletonObjects.put(beanName, bean);
}
// 问题:如果A需要AOP代理,此时bean是原始对象,B拿到的是未代理的A
// 后续A完成初始化后,再生成代理,导致B持有旧引用
三级缓存的必要性:
- 三级缓存存工厂:延迟创建代理对象
- 二级缓存存半成品:缓存工厂创建的结果
- 一级缓存存成品:最终Bean
AOP代理场景:
java
// A需要代理
getEarlyBeanReference("a", mbd, bean) {
// 通过SmartInstantiationAwareBeanPostProcessor创建代理
return createAopProxy(bean);
}
// 如果B需要a,工厂返回的是代理对象
// 确保B持有的是代理后的A
2.4 时序图总结
时间轴 →───────────────────────────────────────────────────────→
创建A
│
├─▶ 实例化A → A对象
│
├─▶ addSingletonFactory() → 三级缓存[ObjectFactory(A)]
│
├─▶ populateBean(A) → 需要B
│ │
│ └─▶ getBean("B")
│ │
│ ├─▶ 实例化B → B对象
│ │
│ ├─▶ addSingletonFactory() → 三级缓存[ObjectFactory(B)]
│ │
│ ├─▶ populateBean(B) → 需要A
│ │ │
│ │ └─▶ getSingleton("A") ←从三级缓存获取
│ │ │
│ │ ├─▶ 一级缓存?无
│ │ ├─▶ 二级缓存?无
│ │ ├─▶ 三级缓存?有 → 调用工厂生成A半成品
│ │ ├─▶ 放入二级缓存
│ │ └─▶ 返回A半成品
│ │
│ ├─▶ B填充A成功
│ │
│ └─▶ initializeBean(B) → B初始化完成
│ │
│ └─▶ addSingleton(B) → 放入一级缓存
│
├─▶ A填充B成功(B已在一级缓存)
│
└─▶ initializeBean(A) → A初始化完成
│
└─▶ addSingleton(A) → 放入一级缓存,清除二、三级缓存
2.5 循环依赖的限制
Spring无法解决的循环依赖:
- 构造器注入循环依赖
java
@Service
public class A {
private final B b;
public A(B b) { // 构造器注入
this.b = b;
}
}
@Service
public class B {
private final A a;
public B(A a) { // 构造器注入
this.a = a;
}
}
// ❌ 报错:BeanCurrentlyInCreationException
// 原因:实例化时需要对方实例,但此时连半成品都未暴露
- prototype作用域循环依赖
java
@Scope("prototype")
@Service
public class A {
@Autowired
private B b;
}
@Scope("prototype")
@Service
public class B {
@Autowired
private A a;
}
// ❌ 报错:Spring不缓存prototype Bean,无法提前暴露
- @Async代理循环依赖
java
@Service
public class A {
@Autowired
private B b;
@Async
public void method() {}
}
@Service
public class B {
@Autowired
private A a;
}
// ❌ 可能报错:A被代理后,B持有的是原始对象,导致类型不匹配
2.6 三级缓存源码验证
关键代码位置:
java
// DefaultSingletonBeanRegistry.java
public class DefaultSingletonBeanRegistry {
// 一级缓存:singletonObjects
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 二级缓存:earlySingletonObjects
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
// 三级缓存:singletonFactories
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
// 获取单例
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
// 添加单例工厂(三级缓存)
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
// 添加完整单例(一级缓存)
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
三、生产实践与避坑指南
3.1 Bean生命周期调试技巧
java
// 方式1:实现生命周期接口
@Component
public class DebugBean implements InitializingBean, DisposableBean, BeanNameAware, ApplicationContextAware {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Bean初始化完成");
}
@Override
public void destroy() throws Exception {
System.out.println("Bean销毁");
}
}
// 方式2:使用@PostConstruct/@PreDestroy(推荐)
@Component
public class DebugBean {
@PostConstruct
public void init() {
System.out.println("PostConstruct");
}
@PreDestroy
public void cleanup() {
System.out.println("PreDestroy");
}
}
// 方式3:注册BeanPostProcessor监听所有Bean
@Component
public class DebugBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
System.out.println("Before: " + beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
System.out.println("After: " + beanName);
return bean;
}
}
3.2 循环依赖检测与解决
检测工具:
bash
# 启动时添加参数
-Dspring.debug=true
# 或使用Spring Boot Actuator
http://localhost:8080/actuator/beans
解决循环依赖的三种方案:
方案1:使用@Lazy延迟注入
java
@Service
public class A {
private final B b;
public A(@Lazy B b) { // 构造器注入时延迟
this.b = b;
}
}
@Service
public class B {
private final A a;
public B(A a) {
this.a = a;
}
}
方案2:使用Setter注入
java
@Service
public class A {
private B b;
@Autowired
public void setB(B b) { // Setter注入可被三级缓存解决
this.b = b;
}
}
方案3:提取公共接口
java
public interface ServiceAbc {
void doSomething();
}
@Service
public class A implements ServiceAbc {
@Autowired
private B b;
}
@Service
public class B {
@Autowired
private ServiceAbc a; // 依赖接口而非具体实现
}
3.3 三级缓存性能影响
内存占用:
java
// 创建过程中,同时存在于三级和二级缓存
A创建中:
- singletonFactories: {a=ObjectFactory@A}
- earlySingletonObjects: {}
- singletonObjects: {}
B创建中,获取A后:
- singletonFactories: {b=ObjectFactory@B}
- earlySingletonObjects: {a=A半成品@A}
- singletonObjects: {}
B创建完成:
- singletonFactories: {}
- earlySingletonObjects: {a=A半成品@A}
- singletonObjects: {b=B成品@B}
A创建完成:
- singletonFactories: {}
- earlySingletonObjects: {}
- singletonObjects: {a=A成品@A, b=B成品@B}
性能损耗 :三级缓存仅在创建期 占用内存,创建完成后立即清理,无长期内存泄漏。
四、核心源码总结
三大缓存操作入口:
java
// 1. 获取单例
getSingleton(String beanName, boolean allowEarlyReference)
// 2. 添加单例工厂(三级缓存)
addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory)
// 3. 添加完整单例(一级缓存)
addSingleton(String beanName, Object singletonObject)
// 4. 移除单例(销毁时)
removeSingleton(String beanName)
生命周期与循环依赖的协同:
java
// AbstractBeanFactory.doGetBean() 是交汇点
protected <T> T doGetBean(...) {
// 先从缓存获取(解决循环依赖)
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null) {
return (T) getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
// 缓存未命中,开始创建
return createBean(beanName, mbd, args); // 触发完整生命周期
}
理解Spring IoC容器的生命周期和循环依赖机制,是掌握Spring框架底层原理的关键。三级缓存是Spring解决单例循环依赖的精妙设计,既保证了Bean的完整性,又避免了构造器注入的死锁问题。