1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Spring面试之循环依赖(allowCircularReferences)

Spring面试之循环依赖(allowCircularReferences)

时间:2024-06-22 10:09:39

相关推荐

Spring面试之循环依赖(allowCircularReferences)

-12-07日下午14:00 字节跳动面试

面试题目

-12-07日下午14:00 参加字节跳动在牛客网的视频面试,自我介绍完,面试官问的第一个问题:我看你的项目中使用了Spring,你简单说一下Spring是怎么解决循环依赖问题的?

循环依赖的概念

说到Spring,大家都熟悉名词IOC,AOP,但是到具体问题,IOC的过程中是怎么解决这个问题的呢?

首先解释一下“循环依赖”,我第一次听这个概念,还是在某次阿里的面试中问到我的,上次懵懵懂懂,面试官只好换了个问题“如果AService中使用了bService,BService中也引用了aService,会出现问题吗?”。现在回想起来,我真是拧了8年的螺丝,就没想过螺丝为啥这么拧。这次一起整理下,遇到面试官这个问题就跟他详聊一下。

Spring的循环依赖分为构造方法的循环依赖field属性的循环依赖,Spring中只解决了单例情况的filed属性的循环依赖问题,对于构造方法的循环依赖和非单例属性的循环依赖还是会报错的,拋出BeanCurrentlyInCreationException异常,在解决属性循环依赖时,spring采用的是提前暴露对象的方法。

Spring怎么解决单例对象的循环依赖

Spring的循环依赖的理论依据基于Java的引用传递,当获得对象的引用时,对象的属性是可以延后设置的,Spring的单例对象的初始化主要分为三步:

1)createBeanInstance:实例化,其实也就是调用对象的构造方法实例化对象

2)populateBean:填充属性,这一步主要是多bean的依赖属性进行填充

3)initializeBean:调用spring xml中的init 方法。

从上面单例bean的初始化可以知道:循环依赖主要发生在第一、二步,也就是构造器循环依赖和field循环依赖。那么我们要解决循环引用也应该从初始化过程着手,对于单例来说,在Spring容器整个生命周期内,有且只有一个对象,所以很容易想到这个对象应该存在Cache中。Spring为了解决单例的field属性的循环依赖(AbstractAutowireCapableBeanFactory的属性allowCircularReferences默认true),使用了三级缓存,这三级缓存分别为:

1). singletonObjects 单例对象的cache,存的是原始对象

2). earlySingletonObjects 提前曝光的单例对象的Cache

3). singletonFactories 单例对象工厂cache, 原始对象,在spring进行的AOP的时候需要原始对象,还需要beanName & RootBeanDefinition,传递了lambda表达式,调用时不会执行:

DefaultSingletonBeanRegistry 只是定义了一个lambda表达式,不会真正去执行。

初始化对象的属性,首先去单例池中查找,如果单例池中没有则到二级缓存中去找,二级缓存中也没有,就判断是否出现了循环依赖。如果出现了循环依赖,实际上不会去判断是否需要AOP,直接去三级缓存中查找,拿到一个lambda表达式(包含原始对象以及对象名称等信息),在执行lambda的过程中,才会去判断是否需要AOP,如果需要AOP则返回代理对象,否则返回原始对象,放到二级缓存中,再从三级缓存中移除掉(因为对象是单例的,如果不移除的话,会有bug,导致重复产生代理对象。)。

一个对象只会出现了二级缓存或者三级缓存中,不能两个缓存都存在,缓存HashMap加锁。

提前进行AOP的逻辑

对于某个service如果需要AOP(@EnableAspectJAutoProxy)的话,要么在第4步AOP,要么在判断出现循环依赖后提前进行AOP。所以在AOP之前,要判断service有没有已经进行过AOP(AOP插件中实现的: AbstractAdvisorAutoProxyCreator.java / AbstactAutoProxyCreator.java),从提前缓存中移除,如果能够移除,则不再进行AOP,否则进行AOP。

如果提前进行了AOP,返回了原始对象,不返回代理对象,放到二级缓存。

参考视频地址:/video/BV1mp4y167UU?p=9

参考代码:/u010853261/article/details/77940767

参考代码:/yxh13521338301/article/details/105264489

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。