先看为什么循环依赖怎么出现的? 比如有AService和BService,具体代码如下:
class AService {
@Autowired
BService b;
}
class BService {
@Autowired
AService a;
}
上面的代码 A中引入了B,B中引入了A,这样当spring实例A的时候,看到@Autowired引入了BService,然后会去实例化BService,实例化BService的时候,属性中又引入了AService,所以又会去实例化AService,如此循环下去产生了循环依赖。
解决方法
在实例化A后(属性注入之前),把它放入一个Map中暂时叫Map1,然后再注入属性,实例化B去,实例化B的时候,B又需要引入A,此时直接从前面的Map1中去取出,
此时取出的A和前面实例化的A是同一个引用。
然后B实例化完并且属性注入完成后,继续执行A的属性注入流程,后续A属性注入也完成了。因为A都是同一个引用,所以此时B中持有的是完整的A实例。
A实例化完整后,再把A放入另一个Map中,这个Map都是放完整的实例化后的类的,上面的Map1存放的是没有注入属性的实例化类。
看样子不需要三级缓存了为什么还需要三级缓存?
三级缓存主要为了解决动态代理的问题。
下图总结的图片
源码细节
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
...
// 从三级缓存中获取实例对象的逻辑,注意这里可能来自于一级缓存/二级缓存/三级缓存
Object sharedInstance = getSingleton(beanName);
// 如果缓存中有,就进行一定的逻辑处理直接返回。
if (sharedInstance != null && args == null) {
// 返回实例对象。
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 调用创建实例的方法
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
}
}
@Nullable
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) {
// 从三级缓存拿,拿出来的是一个FactoryBean
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 调用FactoryBean的getObject方法。这里可能会生成代理对象,也可能是非代理对象
singletonObject = singletonFactory.getObject();
// 生成的对象,放入二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
// 删除三级缓存的类
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
上面重要的方法是createBean,它调用了doCreateBean,它是重要的方法继续分析
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
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");
}
// 重要的方法,注意第二个参数是lamda表达式,看他传入的参数是ObjectFactory,只有一个方法getObject
// 就是在上面getSingleton方法中会去调用触发的。addSingletonFactory会把ObjectFactory对象
// 放入三级缓存中。
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
...
Object exposedObject = bean;
try {
// 属性注入,在这个方法中会再次执行doGetBean方法,第二次再此执行该方法的时候,缓存中就会存在第一次进入的时候实例化好的半成品bean了。
populateBean(beanName, mbd, instanceWrapper);
// 调用各种回调接口
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
继续分析getEarlyBeanReference
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 遍历实现了SmartInstantiationAwareBeanPostProcessor接口的实现类
for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
// 这里是获取FactoryBean实例的
exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);
}
}
return exposedObject;
}
/**
* 此方法是核心,默认的实现是直接返回传入的bean实例
*/
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return bean;
}
这里还有一个SmartInstantiationAwareBeanPostProcessor的实现类,就是生产AOP代理类AbstractAutoProxyCreator,看它的getEarlyBeanReference方法
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
this.earlyProxyReferences.put(cacheKey, bean);
return wrapIfNecessary(bean, beanName, cacheKey);
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
...
// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
// 生成动态代理,这块在我的另一个文档中分析动态代理生成的地方有提到。
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
...
}