Spring-Bean初始化
整体分析了BeanFactory和ApplicationContext的区别。并从Spring Bean创建流程源码分析了bean的创建流程并对其进行总结,并分析了三级缓存的作用
BeanFactory
BeanFactory 是 Spring 最基础的 IoC 容器接口,仅提供了 Bean 的获取与管理能力。而 DefaultListableBeanFactory 是其默认实现类,它通过实现多个关键接口,构建出完整的 IoC 容器功能体系。
以下是 DefaultListableBeanFactory 实现的主要接口以及其对应的职责:
| 主要接口 | 主要功能 |
|---|---|
| AliasRegistry | 提供 Bean 的别名注册和解析能力。允许一个 Bean 在容器中有多个名字,是 Spring IoC 容器灵活命名机制的基础。 |
| BeanDefinitionRegistry | 管理 Bean 的定义信息(BeanDefinition),提供注册、删除、查询等能力。是容器启动期间加载和维护元数据的关键接口。 |
| SingletonBeanRegistry | 管理单例 Bean 的注册与缓存机制,控制 Bean 的生命周期。所有单例 Bean 都存储在 singletonObjects 缓存中。 |
| AutowireCapableBeanFactory | 提供创建 Bean 实例、属性注入、初始化回调、AOP 代理等高级功能。 通常用于手动创建并管理 Bean 的生命周期,比如调用 createBean()、autowireBean() 等。 |
| ConfigurableListableBeanFactory | 是 BeanFactory 的高级配置接口,支持访问所有已注册的 BeanDefinition,还可以注册 BeanPostProcessor组件。常用于容器初始化后对 BeanFactory 进行增强或定制。 |
| HierarchicalBeanFactory | 支持父子容器结构,允许子容器从父容器中查找 Bean,提升模块化和隔离能力。 是实现 ApplicationContext 之间嵌套结构的基础。 |
FactoryBeanRegistrySupport (继承自 AbstractAutowireCapableBeanFactory) |
支持 FactoryBean 机制的关键实现类,负责识别并缓存 FactoryBean 创建的产品对象。比如,当你定义了一个实现 FactoryBean<T> 的类时,容器最终会获取到 T 类型的对象,而不是工厂本身。 |
ApplicationContext
ApplicationContext不仅实现了BeanFactory接口,还多了许多拓展接口,其余接口如下
| 其他接口 | 主要功能 |
|---|---|
| EnvironmentCapable | 获取Environment,可读取各种配置 |
| MessageSource | 国际化消息解析 |
| ApplicationEventPublisher | 支持事件发布/监听机制 |
| ResourcePatternResolver | 支持资源加载,比如 classpath 等路径资源 |
在注解驱动的环境下,常用的 ApplicationContext 实现类为 AnnotationConfigApplicationContext。该类内部封装了一个 DefaultListableBeanFactory 实例,作为底层的 Bean 注册与管理中心,从而继承了 BeanFactory 的全部能力。
而其refresh方法更是容器启动流程的核心。Bean的解析、注册,各种后置处理器的准备、使用,国际化和事件发布、各种监听器均在这个方法中完成,可以说是整个Spring的核心
bean创建流程源码(只保留了重要的部分)
AbstractBeanFactory#doGetBean
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean方法部分关键代码
// 获取真实的beanName,参数name可能是bean的别名和FactoryBean格式(前面有&)
String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// 为了解决循环引用,在这里就必须可以从二级或三级缓存中拿bean(尽管此时这个bean实例化了,还未填充数据和初始化)
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 循环创建多例bean抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 先获取父容器
BeanFactory parentBeanFactory = getParentBeanFactory();
// 父BeanFactory存在且当前的BeanFactory不存在BeanDefinition,就会去父BeanFactory递归查找
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 在父容器中获取bean,能获取到就直接返回了
...
}
if (!typeCheckOnly) {
// 标记bean为已创建
markBeanAsCreated(beanName);
}
try {
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// 有dependsOn的bean,则优先创建这些bean
...
}
// Create bean instance.
if (mbd.isSingleton()) { // 单例bean的创建
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// bean创建失败,执行destory相关方法并直接抛出异常
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) { // 创建多例bean
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else { // 特殊的scope里bean的创建。创建在session,request等scope里面的bean
String scopeName = mbd.getScope();
Scope scope = this.scopes.get(scopeName);
}
// 获取并放入对应的Scope中,在返回bean
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && !requiredType.isInstance(bean)) {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
return (T) bean;
DefaultSingletonBeanRegistry#getSingleton
从三级缓存中获取bean
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 先从一级缓存中直接获取
Object singletonObject = this.singletonObjects.get(beanName);
// 单例bean还没创建好但是正在创建的情况(说明已经有循环引用了)
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 二级缓存中获取
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
synchronized (this.singletonObjects) {
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) {
// 三级缓存不为空,取出该bean,放入二级缓存,同时从三级缓存中删除
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
AbstractAutowireCapableBeanFactory#doCreateBean
// 实例化bean。先创建出一个空壳的bean,各种field和方法都没有填充和调用
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 已实例化的bean
Object bean = instanceWrapper.getWrappedInstance();
// bean 的class type
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// 单例+允许循环引用+当前bean正在创建。就需要将bean包装后放入三级缓存中
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// 将已实例化但还未填充属性的bean放入三级缓存,供其他依赖此bean的bean使用
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 准备初始化bean
Object exposedObject = bean;
try {
// 填充bean的字段(依赖的字段bean)
populateBean(beanName, mbd, instanceWrapper);
// bean完全填充好属性后,开始调用各种初始化方法和BeanPostProcessor接口
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
... // 省略异常
}
...
// 注册destroy相关方法
registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
AbstractAutowireCapableBeanFactory#populateBean
填充bean的字段
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 根据autowireMode来判断注入方式
// 1. xml显示配置的autowire
// 2. 配置了@Bean注解的autowire字段(这个字段默认不会走下面的代码注入)
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
// ==================== 以下就是@Autowired和@Resource注入方式的处理
// 是否存在InstantiationAwareBeanPostProcessor处理器(主要是注解解析PostProcessor)
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
// 获取InstantiationAwareBeanPostProcessor处理器,并调用其postProcessProperties方法
// 基于注解的依赖注入会用到
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 注解相关的自动注入
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
pvs = pvsToUse;
}
}
}
}
AbstractAutowireCapableBeanFactory#initializeBean
初始化bean
// 三种aware(BeanName,BeanClassLoader,BeanFactory)
invokeAwareMethods(beanName, bean);
// 名叫wrappedBean,表示这些方法返回的bean可能是被包装后的,比如aop相关
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// BeanPostProcessor接口实例回调(在bean的初始化方法调用之前调用)
// 例如:@PostConstruct注解的实现
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
// InitializingBean方法和init-method方法
invokeInitMethods(beanName, wrappedBean, mbd);
if (mbd == null || !mbd.isSynthetic()) {
// BeanPostProcessor#postProcessAfterInitialization接口实例回调。
// 在bean的初始化方法调用完成之后调用,说明bean以及初始化完毕,可以实现其他扩展功能了
//比如AOP的实现、 @Scheduled注解实现等
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
三级缓存相关
- 一级缓存(DefaultSingletonBeanRegistry#singletonObjects):存放的是完全初始化好的bean,包括已实例化、填充内部依赖的bean,运行完初始化方法(@PostConstruct、afterPropertiesSet方法、指定的init-method方法)
- 二级缓存(DefaultSingletonBeanRegistry#earlySingletonObjects):存放bean缓存(如果能被AOP,就是AOP对象),但还未填充属性和允许初始化方法
- 三级缓存(DefaultSingletonBeanRegistry#singletonFactories):存放bean的ObjectFactory工厂对象,使用这个工厂对象,可提前暴露出bean的引用(专用来提前暴露AOP对象的方法)
循环依赖的解决方案
首先,Spring 不希望出现 Bean 的循环依赖,但为了应对这种情况,Spring 还是提供了解决办法。
具体做法是(仅在支持循环依赖的配置下生效):在填充字段和初始化之前,Spring 会把每个 Bean 包装成一个 ObjectFactory 对象,并放入三级缓存(DefaultSingletonBeanRegistry#singletonFactories)
当发生循环依赖时,Spring 会触发三级缓存中的 ObjectFactory#getObject 获取该 Bean 的代理对象,并将代理对象放入二级缓存(DefaultSingletonBeanRegistry#earlySingletonObjects)中,这样一来,当其他依赖这个 Bean 的对象需要时,Spring 可以从二级缓存中取到代理后的 Bean,这样就能确保 无论是否 AOP,都能成功填充依赖关系
为什么要三级缓存
三级缓存的核心作用是解决 AOP 对象的暴露问题,特别是在 循环依赖 的场景下
如果没有 AOP,Spring 只需要使用 一级缓存 和 二级缓存 就能解决循环依赖问题。因为没有代理对象,Bean 本身就是可以直接使用的
但Spring是支持AOP的,其设计初衷是希望通过 后置处理器(AnnotationAwareAspectJAutoProxyCreator)来完成 AOP 代理,而不是在 Bean 实例化时立即完成代理。如果没有三级缓存,Spring 就必须在bean实例化后立刻进行代理,将最终的代理bean放入二级缓存用于解决循环依赖 ,这个包装bean的过程提前了,和 Spring 原本的设计理念就冲突了
所以出现了三级缓存,其仅在 循环依赖 的场景下提前暴露 AOP 代理对象。没有循环依赖的情况下,依然使用后置处理器来完成 AOP 代理,走正常流程
依赖注入中未完全初始化对象的问题
如果有3个bean分别为A、B、C,A依赖B和C,B只依赖A,C什么都不依赖,但提供一个方法sayHello使用。
当开始实例化A时,实例化A后将其工厂对象放入三级缓存中,开始填充A属性,发现了B需要填充,开始实例化B,实例化B对象过程中又需要填充其属性A,这时能从三级缓存中取出了A的引用(但此时A不完整),如果B对象有一个初始化方法(@PostConstruct),调用A对象里的C对象的sayHello方法,但由于A此时只是个空壳,就会抛出空指针异常。
总的来说,就是在循环引用依赖主任期间的调用初始化方法时,使用了尚未完全创建好的bean内部某个未注入字段的某个方法,导致抛出NPE,导致服务启动失败
Bean创建流程总结
- 实例化 Bean:创建一个空壳 Bean(即没有依赖注入和初始化的 Bean 对象)
- 放入三级缓存:将 Bean 的工厂对象(
ObjectFactory)放入三级缓存,以便后续处理循环依赖。(是否允许循环依赖取决于AbstractAutowireCapableBeanFactory#allowCircularReferences字段) - 填充依赖(
AbstractAutowireCapableBeanFactory#populateBean):处理 Bean 的依赖注入(如@Autowired和@Resource)。Spring 会从 一级缓存、二级缓存、三级缓存 中查找依赖的 Bean。如果某个依赖 Bean 还未创建,会触发递归创建 - 初始化 Bean(
AbstractAutowireCapableBeanFactory#initializeBean)- 调用
BeanPostProcessor#postProcessBeforeInitialization方法(初始化前的 Hook) - 执行初始化方法:如
@PostConstruct、afterPropertiesSet()、init-method方法等 - 调用
BeanPostProcessor#postProcessAfterInitialization方法(初始化后的 Hook,涉及 AOP 等)
- 调用
- 注册销毁方法(
AbstractBeanFactory#registerDisposableBeanIfNecessary):注册销毁方法,以便在容器关闭时执行 - 创建完成:将 Bean 放入一级缓存,同时从二级缓存和 三级缓存中移除该 Bean 对应的对象