【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的完整性,又避免了构造器注入的死锁问题。

相关推荐
xiaoye370812 小时前
Spring 中高级面试题
spring·面试
枫叶落雨22212 小时前
ShardingSphere 介绍
java
花花鱼12 小时前
Spring Security 与 Spring MVC
java·spring·mvc
言慢行善13 小时前
sqlserver模糊查询问题
java·数据库·sqlserver
专吃海绵宝宝菠萝屋的派大星13 小时前
使用Dify对接自己开发的mcp
java·服务器·前端
大数据新鸟14 小时前
操作系统之虚拟内存
java·服务器·网络
Tong Z14 小时前
常见的限流算法和实现原理
java·开发语言
凭君语未可14 小时前
Java 中的实现类是什么
java·开发语言
He少年14 小时前
【基础知识、Skill、Rules和MCP案例介绍】
java·前端·python
克里斯蒂亚诺更新14 小时前
myeclipse的pojie
java·ide·myeclipse