前言:
学过 Spring 的都知道 Spring 利用三级缓存解决了循环依赖问题,那你知道什么是循环依赖?什么又是三级缓存?本篇将从源码层面分析 Spring 是怎么去利用三级缓存帮我们解决循环依赖问题。
深入理解 Spring IOC 底层实现机制(refresh 方法源码分析)
Spring 源码之 BeanDefinition 加载分析
深入理解 Spring Bean 生命周期(附源码分析)
什么是循环依赖?
简单来说 如果 Bean A 依赖了 Bean B,而 Bean B 又依赖了 Bean A,造成了相互依赖,也就是我们常说的的循环依赖,代码演示如下:
@Service
public class A{
@Resource
private B b;
}
@Service
public class B{
@Resource
private A a ;
}
什么是三级缓存?
三级缓存是 Spring 为了解决循环依赖问题而设计的,在 Spring 源码中是三个 Map 存储,如下:
// 一级缓存 存放完整的Bean(实例化 初始化完成的 bean)
private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
// 二级缓存Map 存放不完整的Bean(只实例化完 还没属性赋值、初始化)
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap(16);
// 三级缓存Map 存放一个Bean的lambda表达式(也是我们常说的早期bean)
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
- 一级缓存(singletonObjects):用来存储成品 Bean 对象,也就是初始化完成可以直接被其他对象引用的对象。
- 二级缓存(earlySingletonObjects):用来存储半成品对象,也就是实例化了但是还没有初始化的对象。
- 三级缓存(singletonFactories):用来存储工厂对象,二级缓存就是从这个工厂中获取的对象,也就是一个 lambda 表达式,这个 lambda 表达式会提前暴露 Bean 对象的引用,执行这个 lambda 表达式会把这个引用放入二级缓存,同时删除三级缓存。
图解 Spring 三级缓存解决循环依赖:
我们用画图的方法来理解一下 Bean A 依赖 Bean B,Bean B又依赖 Bean A 的情况下,Spring 是怎么去进行 Bean A 和 Bean B 的加载的。
Spring 解决循环依赖的核心就是暴露早期对象,将对象的实例化和初始化分开。
循环依赖场景面试问题
源码分析部分较长,我们先把关于 Spring 三级缓存解决循环依赖的常见问题科普一下。
三个缓存对象的查找顺序是什么样子的?
这个问题阅读了源码的都知道是先找一级缓存,找不到再找二级缓存,最后才会找三级缓存。
一级缓存能否解决循环依赖问题?
不能,一级缓存和二级缓存存储的是不同类型的对象,如果只有一级缓存的话,那么成品对象和半成品对象会存放在一起,半成品状态的对象是直接接暴露给其他对象做引用的,放在一起就无法判断哪些是半成品对象那些事成品对象了。
二级缓存能否解决循环依赖问题?
可以解决某些情况下的循环依赖问题,但是有限制条件,不能出现代理对対象,例如 AOP 的场景、事务的场景。
为什么必须要使用三级缓存?
三级缓存的设计目的主要是针对 AOP 等需要代理场景的 Bean 对象,三级缓存是一个单例工厂,这个工厂的目的是延迟实例化阶段生成对象的代理,只有当 Bean 对象真正发生循环依赖时候,才会提前去生成代理对象,否则只会创建一个工厂放入三级缓存中,但是不会通过这个工厂去创建真正的对象,如果没有三级缓存的话,意味着所有 Bean 对象都需要在提前去生成代理对象,这违背了 Spring 的设计,Spring 设计之初是让 Bean 在生命周期的最后一步完成代理,而不是在实例化后就立马完成代理,Spring 结合 AOP 是通过 AnnotationAwareAspectJAutoProxyCreator 这个后置处理器来完成的,在这个后置处理的 postProcessAfterInitialization 方法中对初始化后的 Bean 完成 AOP 代理,如果出现了循环依赖,没有办法,只有给 Bean 先创建代理。
三级缓存为什么不能解决构造器引起的循环依赖?
因为构造器引起的循环依赖是发生在实例化阶段,而 Spring 使用一、二、三级缓存解决循环依赖的思想是把实例化和初始化分开,暴露早期实例化但是没有初始化的对象,构造器引起的循环依赖是发生在实例化阶段,自然就无法使用三级缓存来解决了。
Spring 三级缓存解决循环依赖源码分析
Spring 容器中的 Bean 获取是如下流程:
getBean–>doGetBean–>createBean–>doCreateBean
分析 Spring 使用三级缓存解决循环依赖,实际就是分析获取 Bean 的过程,当然这个过程包含创建 Bean,我们从 doGetBean 方法开始分析。
AbstractBeanFactory#doGetBean 方法源码分析
AbstractBeanFactory#doGetBean 方法在 Spring Bean 生命周期中分析过,本篇重点分析和三级缓存相关的点,比如 this.getSingleton(beanName) 方法。
//AbstractBeanFactory#doGetBean 方法
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
//根据 name 获取beanName 如果是别名会将别名转换为规范的名称
String beanName = this.transformedBeanName(name);
//根据beanName 从容器中获取 bean 对象(包含一级缓存 二级缓存 三级缓存) 本篇分析的重点
Object sharedInstance = this.getSingleton(beanName);
Object bean;
//bean 不为空 直接从IOC 容器中获取 bean
if (sharedInstance != null && args == null) {
if (this.logger.isTraceEnabled()) {
if (this.isSingletonCurrentlyInCreation(beanName)) {
this.logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
} else {
this.logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//对 bean 进行 BeanFactory 的相关操作(不是本次分析的重点)
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {
//表示IOC 容器中没有当前单例 bean
if (this.isPrototypeCurrentlyInCreation(beanName)) {
//IOC 容器中正在创建原型bean 原型bean 中出现循环依赖直接抛出 bean 创建异常
throw new BeanCurrentlyInCreationException(beanName);
}
//获取父级 BeanFactory IOC 容器
BeanFactory parentBeanFactory = this.getParentBeanFactory();
if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
//当前IOC容器的父容器存在 且当前容器中不存在当前beanName的 beanDefinition
//解析指定 Bean 名称的原始名称
String nameToLookup = this.originalBeanName(name);
//父IOC 容器是 AbstractBeanFactory
if (parentBeanFactory instanceof AbstractBeanFactory) {
//继续调用AbstractBeanFactory#doGetBean 方法查询单例bean
return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
}
if (args != null) {
//委派父级IOC 容器根据指定名称和显式的参数查找
return parentBeanFactory.getBean(nameToLookup, args);
}
if (requiredType != null) {
//委派父级IOC 容器根据指定名称和类型去查找
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
//委派父级IOC 容器根据指定名称去查找
return parentBeanFactory.getBean(nameToLookup);
}
//bean 是否需要做类型验证 一般不需要
if (!typeCheckOnly) {
//不需要做类型检查的时候 标记知道beanName 已经在创建中
this.markBeanAsCreated(beanName);
}
try {
//根据指定 beanName 合并 beanDefinition 主要是处理子类 bean 继承父类 bean 的公共属性问题
RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
this.checkMergedBeanDefinition(mbd, beanName, args);
//获取当前bean 的所有依赖bean 名称
String[] dependsOn = mbd.getDependsOn();
String[] var11;
//当前bean 依赖的bean 是否为空 不为空 优先创建依赖bean
if (dependsOn != null) {
var11 = dependsOn;
int var12 = dependsOn.length;
for(int var13 = 0; var13 < var12; ++var13) {
String dep = var11[var13];
//是否存在循环依赖 存在就报异常
if (this.isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//注册各个bean 之间的关系 方便bean 销毁
this.registerDependentBean(dep, beanName);
try {
//创建依赖的bean
this.getBean(dep);
} catch (NoSuchBeanDefinitionException var24) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var24);
}
}
}
//是否是单例bean
if (mbd.isSingleton()) {
//创建bean 对象 并注册给所有依赖的bean 加入 Spring 一级缓存 并从二级 三级缓存中删除
sharedInstance = this.getSingleton(beanName, () -> {
try {
//创建单例bean createBean 方法是重点方法
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
//创建失败显式地从单例缓存中删除实例
this.destroySingleton(beanName);
throw var5;
}
});
//获取指定的bean实例对象
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
//原型bean 每次都会创建一个新的对象
var11 = null;
Object prototypeInstance;
try {
//注册当前创建的原型bean 对象
this.beforePrototypeCreation(beanName);
//创建bean createBean 方法是重点方法
prototypeInstance = this.createBean(beanName, mbd, args);
} finally {
//异常回调 告诉容器 指定的bean 不再创建
this.afterPrototypeCreation(beanName);
}
//获取指定的bean实例对象
bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
//既不是单例bean 也不是原型bean 根据bean 定义的作用域来创建bean
//获取bean的作用域(一般分为单例、原型、request、session、application、)
String scopeName = mbd.getScope();
//获取指定 bean 的作用域
Scope scope = (Scope)this.scopes.get(scopeName);
if (scope == null) {
//bean 作用域为空 抛出异常
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
//匿名内部类 获取一个指定作用域的 bean
Object scopedInstance = scope.get(beanName, () -> {
//注册当前创建的bean 对象
this.beforePrototypeCreation(beanName);
Object var4;
try {
//创建bean createBean 方法是重点方法
var4 = this.createBean(beanName, mbd, args);
} finally {
//异常回调 告诉容器 指定的bean 不再创建
this.afterPrototypeCreation(beanName);
}
return var4;
});
//获取指定的bean实例对象
bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException var23) {
throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton", var23);
}
}
} catch (BeansException var26) {
//bean 创建失败后的清理bean 工作
this.cleanupAfterBeanCreationFailure(beanName);
throw var26;
}
}
//检查bean 的类型
//类型不为空 且bean 不是当前类型
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
//获取bean 的类型转换器 并将类型转换为 requiredType
T convertedBean = this.getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
} else {
return convertedBean;
}
} catch (TypeMismatchException var25) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", var25);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
} else {
return bean;
}
}
DefaultSingletonBeanRegistry#getSingleton(String beanName) 方法源码分析
DefaultSingletonBeanRegistry#getSingleton 方法主要是依次从 Spring 的一、二、三级缓存中获取 Bean 对象,需要注意的是容器启动时候第一次调用 doGetBean 的时候,从 Spring 的一、二、三级缓存中是获取不到 Bean 对象的,
我们继续往下看 this.createBean(beanName, mbd, args) 方法中的 this.doCreateBean(beanName, mbdToUse, args) 方法,doCreateBean 方法真正干活的方法。
//从 Spring IOC 容器中获取单例 bean 方法包装调用 没有实际操作
@Nullable
public Object getSingleton(String beanName) {
return this.getSingleton(beanName, true);
}
//从 Spring 三级缓存中获取单例 bean
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//从一级缓存中获取 bean
Object singletonObject = this.singletonObjects.get(beanName);
//如果一级缓存中获取的bean 为空 且bean 正在创建中
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
//加同步锁
synchronized(this.singletonObjects) {
//从二级缓存中获取 bean
singletonObject = this.earlySingletonObjects.get(beanName);
//二级缓存中bean为空 且bean 允许早期引用
if (singletonObject == null && allowEarlyReference) {
//从三级缓存中获取bean(是lambda表达式)
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//三级缓存中获取的bean 不为空 执行lambda 表达式 得到半成品的 bean
singletonObject = singletonFactory.getObject();
//将半成品的bean 放进二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
//将三级缓存的bean移出
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
DefaultSingletonBeanRegistry#getSingleton (String beanName, ObjectFactory<?> singletonFactory)方法源码分析
当前 getSingleton 方法和上一个 getSingleton 方法的区别在于当前方法会执行 lambda 表达式,并将对象直接从三级缓存加入到一级缓存,并从三级缓存中清除当前对象。
//从 Spring 容器中获取 Bean
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
//同步防止线程安全问题 因为创建过程中也在操作singletonObjects
synchronized(this.singletonObjects) {
//从一级缓存中获取 bean
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
//一级缓存中没有获取到bean
//bean 正在销毁 则抛出异常 bean不允许被创建
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (this.logger.isDebugEnabled()) {
this.logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
//bean 创建前的准备工作
this.beforeSingletonCreation(beanName);
//bean 创建状态的标记
boolean newSingleton = false;
//异常标记
boolean recordSuppressedExceptions = this.suppressedExceptions == null;
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet();
}
try {
//回调方式创建bean 核心
singletonObject = singletonFactory.getObject();
//标记bean 已经被创建
newSingleton = true;
} catch (IllegalStateException var16) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw var16;
}
} catch (BeanCreationException var17) {
BeanCreationException ex = var17;
if (recordSuppressedExceptions) {
Iterator var8 = this.suppressedExceptions.iterator();
while(var8.hasNext()) {
Exception suppressedException = (Exception)var8.next();
ex.addRelatedCause(suppressedException);
}
}
throw ex;
} finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
//单例bean 创建后的处理方法调用 例如删除bean正在创建的记录
this.afterSingletonCreation(beanName);
}
if (newSingleton) {
//是新创建的bean 加入一级缓存
this.addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
//单例bean 加入一级缓存
protected void addSingleton(String beanName, Object singletonObject) {
//同步防止线程安全问题
synchronized(this.singletonObjects) {
//bean 对象加入一级缓存
this.singletonObjects.put(beanName, singletonObject);
//bean 对象从三级缓存中移出
this.singletonFactories.remove(beanName);
//bean 对象从二级缓存中移出
this.earlySingletonObjects.remove(beanName);
//注册bean
this.registeredSingletons.add(beanName);
}
}
AbstractAutowireCapableBeanFactory#doCreateBean方法源码分析
doCreateBean 在 Spring Bean 生命周期中分析过,本次重点关注 DefaultSingletonBeanRegistry#addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory)、AbstractAutowireCapableBeanFactory#populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)和
DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean) 方法。
//AbstractAutowireCapableBeanFactory#doCreateBean
//真正创建Bean的方法
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
//实例bean 的包装对象 beanWrapper 其实就是对bean 的包装
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//如果是单例bean 从 factoryBean 的缓存中移除当前bean (有可能在本Bean创建之前 就有其他Bean把当前Bean给创建出来了 比如依赖注入过程中)
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//根据beanName、bean的定义信息、args创建一个新的实例对象 根据指定bean使用对应的策略创建新的实例 工厂方法 构造函数自动注入 简单实例化 底层使用 cglib代理 和 反射生成实例对象
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
//获取 instanceWrapper 包装的 bean 实例
Object bean = instanceWrapper.getWrappedInstance();
//获取 instanceWrapper 包装的 class
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
//加锁 保证线程安全
synchronized(mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//允许后置处理器修改合并后的 beanDefinition 将 工厂中的所有 MergedBeanDefinitionPostProcessors 应用到mbd 调用这些后处理器的 postProcessMergedBeanDefinition 方法
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable var17) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
}
//标记该 beanDefinition 已经应用过 工厂中的所有 MergedBeanDefinitionPostProcessors
mbd.postProcessed = true;
}
}
//判断是否需要暴露早期单例对象(解决循环依赖问题)
//单例对象 允许循环引用 单例对象正在创建中 满足三个条件 则需要暴露早期单例对象
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if (earlySingletonExposure) {
//需要暴露早期单例对象
if (this.logger.isTraceEnabled()) {
this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
}
//这里创建了一个匿名的ObjectFactory 工厂 可以用来获取对象
//addSingletonFactory 方法会将这个 匿名的ObjectFactory 工厂 放入到 singletonFactories 中 singletonFactories 是 Spring 的三级缓存
//为了避免循环依赖 尽早的持有对象的引用
//本次重点关注的方法 三级缓存
this.addSingletonFactory(beanName, () -> {
return this.getEarlyBeanReference(beanName, mbd, bean);
});
}
//Bean对象的初始化 依赖注入在此触发
//这个exposedObject在初始化完成之后返回作为依赖注入完成后的Bean
Object exposedObject = bean;
try {
//bean 的属性填充 将bean 对象的实例封装 将Bean定义中配置的属性值赋值给实例对象 包括依赖的 bean
this.populateBean(beanName, mbd, instanceWrapper);
//bean 的初始化 包括应用工厂回调以及init方法和BeanPostProcessors
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
} catch (Throwable var18) {
if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
throw (BeanCreationException)var18;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
}
//第二次解决循环依赖问题
if (earlySingletonExposure) {
//需要暴露早期对象
//从一级 二级缓存中获取bean 对象
//把对象加入到二级缓存中本次重点分析的方法
Object earlySingletonReference = this.getSingleton(beanName, false);
if (earlySingletonReference != null) {
//bean 对象不为空 根据名称获取的已注册的Bean和正在实例化的Bean是同一个
if (exposedObject == bean) {
//当前实例化的Bean初始化完成
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
//当前Bean依赖其他Bean 并且当发生循环引用时不允许新创建实例对象
//获取当前bean 依赖的其他bean
String[] dependentBeans = this.getDependentBeans(beanName);
//实际依赖的bean
Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
String[] var12 = dependentBeans;
int var13 = dependentBeans.length;
//遍历依赖的bean
for(int var14 = 0; var14 < var13; ++var14) {
String dependentBean = var12[var14];
//删除给定Bean名称的单例实例 但仅当它没有用于类型检查之外的其他目的时才删除
if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
//没有删除的bean 加入到实际依赖的bean 中
actualDependentBeans.add(dependentBean);
}
}
//因为bean创建后其所依赖的bean一定是已经创建的 actualDependentBeans不为空则表示当前的bean创建后其依赖的bean却没有全部创建完 说明勋在循环依赖
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
try {
//注册为一次性的bean 也就是处理Bean销毁前要执行的方法
this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
} catch (BeanDefinitionValidationException var16) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
}
}
DefaultSingletonBeanRegistry#addSingletonFactory 方法源码分析
DefaultSingletonBeanRegistry#addSingletonFactory 方法只做了一件事,就是把早期 Bean 对象放入三级缓存。
//添加单例bean对象到三级缓存
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
//同步防止线程安全问题
synchronized(this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
//三级缓存中不存在 bean 对象 bean 对象加入三级缓存
this.singletonFactories.put(beanName, singletonFactory);
//从二级缓存中移出 bean 对象
this.earlySingletonObjects.remove(beanName);
//注册单例bean
this.registeredSingletons.add(beanName);
}
}
}
AbstractAutowireCapableBeanFactory#populateBean方法源码分析
populateBean 方法就是给对象属性赋值,在 Spring Bean 生命周期中也分析过,本次我们主要分析 populateBean 方法中的 this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs) 这行代码,也就是 AbstractAutowireCapableBeanFactory#applyPropertyValues 方法。
//AbstractAutowireCapableBeanFactory#populateBean
//将bean 属性设置到生成的实例对象上
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
//BeanWrapper 为空 且有依赖的属性 直接抛异常
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
} else {
//在设置属性之前 给任何InstantiationAwareBeanPostProcessors一个修改bean状态的机会
if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
Iterator var4 = this.getBeanPostProcessorCache().instantiationAware.iterator();
while(var4.hasNext()) {
InstantiationAwareBeanPostProcessor bp = (InstantiationAwareBeanPostProcessor)var4.next();
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
//获取容器在解析Bean定义资源时为BeanDefiniton中设置的属性值
PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
//依赖注入的逻辑
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == 1 || resolvedAutowireMode == 2) {
//MutablePropertyValues是PropertyValues具体的实现类
MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
if (resolvedAutowireMode == 1) {
//ByName
this.autowireByName(beanName, mbd, bw, newPvs);
}
if (resolvedAutowireMode == 2) {
//ByType
this.autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
// 获取是否有实现InstantiationAwareBeanPostProcessor的方法 这里主要使用postProcessProperties方法。
boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
// 获取是否需要进行依赖注入
boolean needsDepCheck = mbd.getDependencyCheck() != 0;
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
// 属性为空 从beanDefinition中获取需要注入的信息
pvs = mbd.getPropertyValues();
}
PropertyValues pvsToUse;
for(Iterator var9 = this.getBeanPostProcessorCache().instantiationAware.iterator(); var9.hasNext(); pvs = pvsToUse) {
//这里会调用AutowiredAnnotationBeanPostProcessor的 postProcessProperties()方法 会直接给对象中的属性赋值 真正的处理@Autowired @Resource @Value 等注解
//AutowiredAnnotationBeanPostProcessor内部并不会处理pvs。直接返回自己设置的PropertyValues对象(可以在实例化前设置)。
InstantiationAwareBeanPostProcessor bp = (InstantiationAwareBeanPostProcessor)var9.next();
//这里的含义是程序员自己已经给属性赋值了,就不需要Spring给他赋值。这里是程序员没有赋值,所以需要Spring进行赋值
pvsToUse = bp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
//设置值
pvsToUse = bp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
}
}
//是否需要属性注入
if (needsDepCheck) {
if (filteredPds == null) {
//为空 则初始化
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
//检查依赖
this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
}
if (pvs != null) {
//应用给定的属性值 解决任何在这个bean工厂运行时其他bean的引用 必须使用深拷贝 所以我们不会永久地修改这个属性
this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
}
}
}
AbstractAutowireCapableBeanFactory#applyPropertyValues 方法源码分析
AbstractAutowireCapableBeanFactory#applyPropertyValues 方法很长,作用是应用给定的属性值,解决任何在这个 bean 工厂运行时其他bean的引用必须使用深拷贝,所以我们不会永久地修改这个属性,关于这些功能我们不需要要关注那么多,重点关注 Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue) 这行代码,我们接着看。
//应用给定的属性值 解决任何在这个bean工厂运行时其他bean的引用 必须使用深拷贝 所以我们不会永久地修改这个属性
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
//PropertyValues 是否有属性判断 没有属性不处理
if (!pvs.isEmpty()) {
//如果有安全控制 且 bw 是 BeanWrapperImpl 的实例
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
//设置 BW 安全上下文为访问控制山下文
((BeanWrapperImpl)bw).setSecurityContext(this.getAccessControlContext());
}
//MutablePropertyValues 是 PropertyValues接口的默认实现 允许对属性进行简单操作 并提供构造函数来支持从映射 进行深度复制和构造等
MutablePropertyValues mpvs = null;
//原始属性值列表
List original;
//判断 pvs 是否是 MutablePropertyValues
if (pvs instanceof MutablePropertyValues) {
//是就强转
mpvs = (MutablePropertyValues)pvs;
//mpvs 是否需要转换
if (mpvs.isConverted()) {
try {
//设置属性值
bw.setPropertyValues(mpvs);
return;
} catch (BeansException var18) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", var18);
}
}
//获取 mpvs 属性列表
original = mpvs.getPropertyValueList();
} else {
//获取 pvs 属性列表
original = Arrays.asList(pvs.getPropertyValues());
}
//获取工厂自定义类型转换器
TypeConverter converter = this.getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
//BeanDefinition 解析
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, (TypeConverter)converter);
//创建一个深拷贝
List<PropertyValue> deepCopy = new ArrayList(original.size());
//是否需要解析标志
boolean resolveNecessary = false;
//迭代遍历
Iterator var11 = original.iterator();
while(true) {
while(var11.hasNext()) {
//获取 PropertyValue
PropertyValue pv = (PropertyValue)var11.next();
if (pv.isConverted()) {
//已经转换 直接加入到 深拷贝中
deepCopy.add(pv);
} else {
//获取 pv 属性名称
String propertyName = pv.getName();
//获取 pv 属性值
Object originalValue = pv.getValue();
//是否 自动生成标记的规范实例
if (originalValue == AutowiredPropertyMarker.INSTANCE) {
//获取写方法(set)
Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
if (writeMethod == null) {
//写方法为空 抛出异常
throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
}
//将 writeMethod 封装到 DependencyDescriptor 中
originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
}
// valueResolver 根据 pv 解析出 originalValue 所封装的对象 重点方法(循环依赖的对象从这里进去)
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
//解析出来的值
Object convertedValue = resolvedValue;
//可转换标记 propertyName 是否 在bw中的可写属性
//prepertyName不是表示索引属性或嵌套属性
boolean convertible = bw.isWritableProperty(propertyName) && !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
//是否可转换
if (convertible) {
//将 resolvedValue 转换为指定的目标属性对象
convertedValue = this.convertForProperty(resolvedValue, propertyName, bw, (TypeConverter)converter);
}
//resolvedValue 与 originalValue 是否同一个对象
if (resolvedValue == originalValue) {
//是否可转换
if (convertible) {
// convertedValue 设置 给 PV
pv.setConvertedValue(convertedValue);
}
//加入到 deepCopy 中
deepCopy.add(pv);
} else if (convertible && originalValue instanceof TypedStringValue && !((TypedStringValue)originalValue).isDynamic() && !(convertedValue instanceof Collection) && !ObjectUtils.isArray(convertedValue)) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
} else {
//标记为还需要解析
resolveNecessary = true;
//构建对象 加入到 deepCopy 中
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {
//mpvs 不为空 且 不需要再解析 将此 holder 标记为只包含转换后的值
mpvs.setConverted();
}
try {
//使用 deepCopy 构造一个新的 MutablePropertyValues 对象 设置到 bw 中以对 bw 的属性值更新
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
return;
} catch (BeansException var19) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", var19);
}
}
}
}
BeanDefinitionValueResolver#resolveValueIfNecessary 方法源码分析
BeanDefinitionValueResolver#resolveValueIfNecessary 方法主要是对参数进行判断后继续调用方法。
//给定一个PropertyValue 返回一个值 必要时解析对工厂中其他bean的引用
@Nullable
public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
//是否是运行是 bean 引用
if (value instanceof RuntimeBeanReference) {
//循环依赖是运行时 bean 引用 循环依赖分析的重点
RuntimeBeanReference ref = (RuntimeBeanReference)value;
return this.resolveReference(argName, ref);
} else if (value instanceof RuntimeBeanNameReference) {
String refName = ((RuntimeBeanNameReference)value).getBeanName();
refName = String.valueOf(this.doEvaluate(refName));
if (!this.beanFactory.containsBean(refName)) {
throw new BeanDefinitionStoreException("Invalid bean name '" + refName + "' in bean reference for " + argName);
} else {
return refName;
}
} else if (value instanceof BeanDefinitionHolder) {
BeanDefinitionHolder bdHolder = (BeanDefinitionHolder)value;
return this.resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
} else if (value instanceof BeanDefinition) {
BeanDefinition bd = (BeanDefinition)value;
String innerBeanName = "(inner bean)#" + ObjectUtils.getIdentityHexString(bd);
return this.resolveInnerBean(argName, innerBeanName, bd);
} else {
//非重点 不分析
}
}
BeanDefinitionValueResolver#resolveReference 方法源码分析
BeanDefinitionValueResolver#resolveReference 让我们看到熟悉的 getBean 方法,如果 Bean A 依赖了 Bean B,而 Bean B 又依赖了 Bean A,假设 Bean A 先创建,那这里的 getBean 方法就是去获取 Bean B,也就是重新走一遍 Bean A 的流程,循环依赖的循环来了。
//解析应用的属性值
@Nullable
private Object resolveReference(Object argName, RuntimeBeanReference ref) {
try {
//获取 bean 类型
Class<?> beanType = ref.getBeanType();
Object bean;
//引用对象是否在父容器中 在父容器中 就从父容器获取对象
if (ref.isToParent()) {
BeanFactory parent = this.beanFactory.getParentBeanFactory();
if (parent == null) {
throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Cannot resolve reference to bean " + ref + " in parent factory: no parent factory available");
}
if (beanType != null) {
bean = parent.getBean(beanType);
} else {
bean = parent.getBean(String.valueOf(this.doEvaluate(ref.getBeanName())));
}
} else {
//不在父容器中
String resolvedName;
if (beanType != null) {
NamedBeanHolder<?> namedBean = this.beanFactory.resolveNamedBean(beanType);
bean = namedBean.getBeanInstance();
resolvedName = namedBean.getBeanName();
} else {
//获取 resolvedName 引用包装的 bean 名称
resolvedName = String.valueOf(this.doEvaluate(ref.getBeanName()));
//获取 resolvedName 的bean 对象--此处重点来了 又看到 getBean 方法了 熟悉的感觉来了
bean = this.beanFactory.getBean(resolvedName);
}
this.beanFactory.registerDependentBean(resolvedName, this.beanName);
}
if (bean instanceof NullBean) {
bean = null;
}
return bean;
} catch (BeansException var7) {
throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, var7);
}
}
DefaultSingletonBeanRegistry#getSingleton方法源码分析
DefaultSingletonBeanRegistry#getSingleton方法主要就是从三级缓存获取到对象,执行 lambda 表达式,并把得到的对象放入到二级缓存中,同时删除三级缓存的对象,DefaultSingletonBeanRegistry#getSingleton 方法中获取的 bean 对象和 DefaultSingletonBeanRegistry#addSingletonFactory 方法中的 Bean 对象的区别是两个方法之间是调用了 populateBean 方法的,也就是精力属性赋值,对象的属性值是有变化的。
//从缓存中获取 bean 对象
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//从一级缓存中获取对象
Object singletonObject = this.singletonObjects.get(beanName);
//一级缓缓存中没有获取到对象且单例对象正在创建中
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
//同步防止线程安全问题
synchronized(this.singletonObjects) {
//从二级缓存中获取对象
singletonObject = this.earlySingletonObjects.get(beanName);
//二级缓存中对象为空且bean 对象允许暴露早期引用
if (singletonObject == null && allowEarlyReference) {
//从三级缓存中获取bean 对象(获取到的是lambda表达式)
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//执行lambda表达式 也是回调 获取到 bean 对象
singletonObject = singletonFactory.getObject();
//bean 对象保存到二级缓存中(半成品对象)--这里的对象是经过了 populateBean 属性赋值的
this.earlySingletonObjects.put(beanName, singletonObject);
//从三级缓存中移出早期对象
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
至此,Spring 三级缓存相关源码已经分析完毕,希望可以帮助到有需要的小伙伴。
欢迎提出建议及对错误的地方指出纠正。