Spring压轴题:当循环依赖遇上Spring AOP
Spring壓軸題:當(dāng)循環(huán)依賴遇上Spring AOP
前言
問 :Spring如何解決循環(huán)依賴 ?
答:Spring通過提前曝光機制 ,利用三級緩存解決循環(huán)依賴(這原理還是挺簡單的,參考 :三級緩存 、圖解循環(huán)依賴原理)
再問:Spring通過提前曝光 ,直接曝光到二級緩存已經(jīng)可以解決循環(huán)依賴問題了,為什么一定要三級緩存?
再細(xì)問:如果循環(huán)依賴的時候,所有類又都需要Spring AOP自動代理 ,那Spring如何提前曝光 ?曝光的是原始bean還是代理后的bean?
這些問題算是Spring源碼的壓軸題了,如果這些問題都弄明白,恭喜你順利結(jié)業(yè)Spring源碼了 。就單單對Spring這一塊的理解,不夸張的說可以達(dá)到阿里水準(zhǔn)了
源碼分析
進(jìn)入正題 ,在Spring創(chuàng)建Bean的核心代碼doGetBean中 ,在實例化bean之前,會先嘗試從三級緩存獲取bean,這也是Spring解決循環(huán)依賴的開始
(一) 緩存中獲取bean
// AbstractBeanFactory.javaprotected T doGetBean(final String name, @Nullable final ClassrequiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); Object bean; // 2. 嘗試從緩存中獲取bean Object sharedInstance = getSingleton(beanName); ...} protected Object getSingleton(String beanName, boolean allowEarlyReference) { // 從一級緩存獲取 ,key=beanName value=bean Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { // 從二級緩存獲取,key=beanName value=bean singletonObject = this.earlySingletonObjects.get(beanName); // 是否允許循環(huán)引用 if (singletonObject == null && allowEarlyReference) { /** * 三級緩存獲取,key=beanName value=objectFactory