模拟案例:
ServiceA注入ServiceB,ServiceB注入ServiceA,下列代码首先创建Bean:ServiceA,ServiceA会依赖注入ServiceB,整体依赖注入流程如下:
判断当前bean是否在创建的关键在于
DefaultSingletonBeanRegistry类中的 public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) 调用的beforeSingletonCreation(beanName)方法放入当前bean正在创建。
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
- bean首先实例化,然后放入三级缓存(源码如下):
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
() -> getEarlyBeanReference(beanName, mbd, bean)是传入一个实现类方法,实现了ObjectFactory接口的getObject()方法。
2.进行属性注入,doCreateBean中调用方法注入ServiceB
populateBean(beanName, mbd, instanceWrapper);
3.调用DefaultListableBeanFactory类的方法doResolveDependency:
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter)
调用链路中,方法走向最后具体执行代码是:
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
4.发现ServiceB未实例化,调用DependencyDescriptor类的方法开始重新执行getBean创建ServiceB:
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
throws BeansException {
return beanFactory.getBean(beanName);
}
以上就是循环依赖整体流转的核心流程。
**1) 核心思想流程:
- A初始化过程中先将自己放入三级缓存,A属性注入B,B执行初始化,首先也是放入三级缓存,B属性注入A,在获取A的时候将A从三级缓存移入二级缓存并返回(返回的对象可能是AOP代理后的对象,是与不是取决于当前注入的A是否有代理的需求,调用:getEarlyBeanReference方法判断是否代理),此时B注入A成功。
- B执行完整的Spring生命周期后(也可能是个AOP对象,这里执行的BeanPostProcessor后置方法进行AOP代理判断:关键点在于当前bean是否被其他bean注入的时候是否执行过aop代理的代码,也就是getEarlyBeanReference()方法是否执行过,因为执行过会在AOP代理类的缓存中存在: this.earlyProxyReferences.remove(cacheKey) != bean 这里判断是否代理过,没代理过才执行aop代理操作,否则直接返回bean)放入一级缓存并将二级三级缓存中的B删除,并递归返回到A注入B,从一级缓存中拿到B,并注入成功。 **
2) 三级缓存的意义:为了注入的是代理对象!
- 核心代码在AbstractAutoProxyCreator类中:
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
//缓存当前bean,证明自己被代理执行过了
this.earlyProxyReferences.put(cacheKey, bean);
//返回代理对象:如果当前对象有代理需求,没有就直接返回当前bean
return wrapIfNecessary(bean, beanName, cacheKey);
}
在获取三级缓存的时候,ObjectFactory接口执行getObject方法:
protected 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) {
synchronized (this.singletonObjects) {
// 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) {
//执行是否进行代理的操作,最终执行的是getEarlyBeanReference()方法
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
- 每个bean的生命周期最后会执行BeanPostProcessor的后置通知方法postProcessAfterInitialization(),从代理实现类中移除当前bean,只有在初始化中没:
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
//如果当前bean不存在缓存中,也就是没被代理过
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
//则选择aop代理:代理与不代理取决于当前bean是否有需求
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}