【Spring】IoC容器深度解析:Bean生命周期与循环依赖三级缓存

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;
}

创建过程分析

  1. 创建A,实例化后填充属性b
  2. b未创建,开始创建B
  3. B实例化后填充属性a
  4. 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无法解决的循环依赖

  1. 构造器注入循环依赖
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
// 原因:实例化时需要对方实例,但此时连半成品都未暴露
  1. 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,无法提前暴露
  1. @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的完整性,又避免了构造器注入的死锁问题。

相关推荐
我爱娃哈哈15 小时前
SpringBoot + Aviator + 规则中心:轻量级表达式引擎实现营销优惠动态计算
java·spring boot·后端
珂朵莉MM15 小时前
2025年睿抗机器人开发者大赛CAIP-编程技能赛-高职组(国赛)解题报告 | 珂学家
java·开发语言·人工智能·算法·机器人
a努力。16 小时前
虾皮Java面试被问:JVM Native Memory Tracking追踪堆外内存泄漏
java·开发语言·jvm·后端·python·面试
学习是生活的调味剂16 小时前
Java IO模型之BIO和NIO分析
java·nio
Knight_AL16 小时前
Redis ZSet 实现排行榜(支持分数相同按时间顺序排序)
数据库·redis·缓存
笙枫16 小时前
基于AI Agent框架下的能源优化调度方案和实践 |工具函数介绍(详细)
java·人工智能·能源
我命由我1234516 小时前
Android Studio - Android Studio 去除 import 的未使用的类
android·java·ide·学习·java-ee·android studio·学习方法
沛沛老爹16 小时前
Skills高级设计模式(一):向导式工作流与模板生成
java·人工智能·设计模式·prompt·aigc·agent·web转型