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对象的方法)
为什么要使用三级缓存
三级缓存专门来解决AOP对象的暴露问题。
如果没用AOP是可以只用一级缓存和二级缓存就解决的。但如果使用了AOP且没有三级缓存,那么必须在实例化后就马上完成AOP代理,但这和spring的设计初衷不同,AOP代理的完成时使用了bean的后置处理器AnnotationAwareAspectJAutoProxyCreator来完成的,也就是在初始化bean后执行的bean后置处理器方法(AbstractAutowireCapableBeanFactory#initializeBean),就不可能再实例化bean后进行代理,所以才有了三级缓存,仅用来提前暴露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(空壳bean)的某个字段的方法,导致抛出NPE,导致服务启动失败
关键流程总结
- 实例化bean:创建bean的空壳对象
- 将其工厂对象(ObjectFactory)放入三级缓存(根据AbstractAutowireCapableBeanFactory#allowCircularReferences字段决定)
- 填充依赖bean(AbstractAutowireCapableBeanFactory#populateBean):进行@Autowired和@Resource等注解的字段注入。如果这些依赖的 Bean 还没创建,会触发递归创建
- 初始化bean(AbstractAutowireCapableBeanFactory#initializeBean)
- 4.1 调用BeanPostProcessor#postProcessBeforeInitialization方法(初始化前的hook)
- 4.2 调用各种初始化方法(**@PostConstruct、afterPropertiesSet方法、指定的init-method方法**)
- 4.3 调用BeanPostProcessor#postProcessAfterInitialization(初始化后的hook,AOP相关实现)
- 注册destory相关方法(AbstractBeanFactory#registerDisposableBeanIfNecessary)
- 完成创建,放入一级缓存。同时移除三级缓存和二级缓存中的相关对象