在springBean单例模式下:
Spring 单例 Bean 的创建核心逻辑位于 AbstractAutowireCapableBeanFactory 类的 doCreateBean 方法中。整个过程可以概括为:实例化 -> 属性填充 -> 初始化 -> 注册销毁回调。
以下是基于 Spring Framework 5.x/6.x 的核心源码流程解析:
-
入口:getBean -> doGetBean -> createBean
当调用 context.getBean("beanName") 时,最终会进入 AbstractAutowireCapableBeanFactory.doCreateBean。
-
核心步骤详解 (doCreateBean)
第一步:实例化 (Instantiation)
创建 Bean 的原始对象(Raw Object),此时属性尚未填充。
java
// AbstractAutowireCapableBeanFactory.java
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) {
// 1. 实例化 Bean
BeanWrapper instanceWrapper = null;
if (instanceWrapper == null) {
// createBeanInstance 负责推断构造方法并反射创建对象
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 获取原始对象实例
Object bean = instanceWrapper.getWrappedInstance();
// ... 省略早期引用暴露逻辑(解决循环依赖的关键) ...
}
关键点:这里通过 instantiateBean 使用反射调用构造函数。如果存在工厂方法或 Supplier,也会在此处理。
第二步:属性填充 (Populate Bean)
将依赖注入到 Bean 中(即处理 @Autowired, @Value, 等)。
java
// 2. 属性填充
populateBean(beanName, mbd, instanceWrapper);
关键点:
populateBean 会先执行 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation。
然后解析依赖关系,递归调用 getBean 获取依赖项。
最后通过反射或 Setter 方法将依赖注入到当前 Bean 中。
第三步:初始化 (Initialization)
执行 Bean 的生命周期回调方法。
java
// 3. 初始化 Bean
exposedObject = initializeBean(beanName, exposedObject, mbd);
initializeBean 内部执行顺序非常严格:
Aware 接口回调:
如果 Bean 实现了 BeanNameAware, BeanFactoryAware, ApplicationContextAware 等,此时调用 setBeanName, setBeanFactory 等方法。
前置处理器 (BeanPostProcessor.postProcessBeforeInitialization):
执行所有注册的 BPP 的 postProcessBeforeInitialization 方法。
重要:@PostConstruct 注解的方法通常由 CommonAnnotationBeanPostProcessor 在此阶段执行。
自定义初始化方法:
如果 Bean 实现了 InitializingBean 接口,调用 afterPropertiesSet()。
如果配置了 init-method,通过反射调用该方法。
后置处理器 (BeanPostProcessor.postProcessAfterInitialization):
执行所有注册的 BPP 的 postProcessAfterInitialization 方法。
重要:AOP 代理对象通常在此阶段创建(如 AnnotationAwareAspectJAutoProxyCreator)。如果生成了代理对象,此处返回的是代理对象而非原始对象。
第四步:注册销毁回调 (Register Disposable Bean)
如果 Bean 是单例且定义了销毁方法,将其注册到容器中,以便容器关闭时执行。
java
// 4. 注册销毁回调
registerDisposableBeanIfNecessary(beanName, bean, mbd);
- 循环依赖的处理(三级缓存)
在单例 Bean 创建过程中,Spring 通过三级缓存解决单例字段的循环依赖问题:
一级缓存 (singletonObjects):存放完全初始化好的 Bean。
二级缓存 (earlySingletonObjects):存放原始的 Bean 对象(尚未填充属性),用于解决循环依赖时的提前暴露。
三级缓存 (singletonFactories):存放 ObjectFactory,主要用于处理 AOP 代理。如果 Bean 需要被代理,则通过工厂提前生成代理对象放入二级缓存。
流程简述:
A 依赖 B,B 依赖 A。
A 实例化后,将 A 的工厂放入三级缓存。
A 填充属性时发现需要 B,去创建 B。
B 填充属性时发现需要 A,调用 getBean("A")。
此时 A 未创建完成,但在三级缓存中有工厂。Spring 调用工厂获取 A 的早期引用(如果有 AOP 则生成代理),放入二级缓存。
B 拿到 A 的早期引用,完成 B 的创建。
A 拿到完整的 B,完成 A 的创建。
下面就看下spring解决三级缓存的核心源码:
核心就3个map,用来存放bean
java
## 一级缓存存放完整的bean
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
## 三级缓存是存放bean工厂的,作用是用来生产早期的bean
/** Creation-time registry of singleton factories: bean name to ObjectFactory. */
private final Map<String, ObjectFactory<?>> singletonFactories = new ConcurrentHashMap<>(16);
## 二级缓存是用来存放早期未初始化完成的bean
/** Cache of early singleton objects: bean name to bean instance. */
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
java
protected @Nullable Object getSingleton(String beanName, boolean allowEarlyReference) {
// Quick check for existing instance without full singleton lock.
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
if (!this.singletonLock.tryLock()) {
// Avoid early singleton inference outside of original creation thread.
return null;
}
try {
// Consistent creation of early reference within full singleton lock.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
// Singleton could have been added or removed in the meantime.
if (this.singletonFactories.remove(beanName) != null) {
this.earlySingletonObjects.put(beanName, singletonObject);
}
else {
singletonObject = this.singletonObjects.get(beanName);
}
}
}
}
}
finally {
this.singletonLock.unlock();
}
}
}
return singletonObject;
}
上面这段核心代码不用解读了吧,如果看不懂让AI来帮你解释一下,今天就分享到这里,下次我们在讨论为啥要设计3级缓存,2级不行吗?