spring循环依赖
AOP
AbstractAutowireCapableBeanFactory
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//默认情况下开启aop后这里的对象会从6个变成7个
for (BeanPostProcessor processor : getBeanPostProcessors()) {
//调用每个bean初始化后的方法
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
添加注解@EnableAspectJAutoProxy
理论上俩个map就能解决循环依赖
但是进行AOP应该是初始化后去进行的,不符合bean生命周期的设计,而且代理对象中存在着target对象是用来存放
在当前类出现了循环依赖的情况下才需要提前进行aop
三级缓存
- singletonObjects:缓存经过了完整生命周期的bean
- earlySingletonObject:缓存未经过完整生命周期的bean,如果bean出现了循环依赖,就会吧这个暂时未经过完整生命周期的bean放入ealySingletonObject中,这个bean如果要经过AOP,那么就会把代理对象放入earlySingletonObjects中,否则就是把原始对象放入earlySingletonObjects,但不管怎么样,就是代理对象,代理对象锁代理的原始对象也是没有经过完整生命周期的,所以放入earlySingletonObjects我们就可以统一认为是未经过完整生命周期的bean。
- singletonFactories:缓存的是一个ObjectFatory。也就是一个lambda表达式,每个Bean的生成过程中经过实例化得到一个原始对象后,都会提前基于原始对象暴露一个lambda表达式,并保存到三级缓存中,这个lambda表达式可能用到,也可能用不到,如果当前bean没有出现循环依赖,那么这个lambda表达式没用,当前bean按照自己的生命周期正常执行,执行完后直接把bean放入SingletonObjects中,如果当前bean在依赖注入时发现了循环依赖(当前正在创建的bean被其他的bean依赖了),从三级缓存中拿到lambda表达式,并执行lambda表达式得到一个对象,并把得到的对象放入二级缓存(如果当前bean需要AOP,那么执行lambda表达式,得到就是对应的代理对象,如果无需aop),它用来记录某个原始对象是否进行过AOP了
- 其实还要一个缓存,就是ealyProxyReferences,它用来记录某个对象是否进行过aop了
比如A和BService出现了循环依赖