国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

[Spring] 三級緩存解決循環(huán)依賴詳解

這篇具有很好參考價值的文章主要介紹了[Spring] 三級緩存解決循環(huán)依賴詳解。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

什么是循環(huán)依賴

注冊一個bean對象的過程:
Spring掃描class得到BeanDefinition – 根據(jù)得到的BeanDefinition去生成bean – 現(xiàn)根據(jù)class推斷構(gòu)造方法 – 根據(jù)推斷出來的構(gòu)造方法,反射,得到一個對象 – 填充初始對象中的屬性(依賴注入) – 如果原始對象種的某個方法被AOP了,那么要根據(jù)原始對象生成一個代理對象 – 把最終生成的代理對象放入單例池(singletonObjects,也叫一級緩存)中,下次getBea你就直接從單例池拿

循環(huán)依賴就是在依賴注入的時候相互注入,如

public class AService{
	@Autowired
	private BService bService;
}
public class BService{
	@Autowired
	private AService aService;
}

三級緩存過程

Spring使用了三級緩存的策略來解決循環(huán)依賴問題,過程大致如下
創(chuàng)建AService的bean:
[Spring] 三級緩存解決循環(huán)依賴詳解,spring,緩存,java
因為暫時還沒有BService,所以創(chuàng)建個BService
[Spring] 三級緩存解決循環(huán)依賴詳解,spring,緩存,java
創(chuàng)建過程中,因為AService已經(jīng)在三級緩存中出現(xiàn)過,所以會進行以下操作
[Spring] 三級緩存解決循環(huán)依賴詳解,spring,緩存,java
因為BService的屬性都已經(jīng)賦值了,所以BService的初始化就結(jié)束了,可以直接放到一級緩存中,完整過程為:
[Spring] 三級緩存解決循環(huán)依賴詳解,spring,緩存,java
此時BService已經(jīng)實例化完成,那么AService中的依賴就可以進行注入了:
[Spring] 三級緩存解決循環(huán)依賴詳解,spring,緩存,java
完整流程圖如下:
[Spring] 三級緩存解決循環(huán)依賴詳解,spring,緩存,java

簡單的源碼解析

首先在AbstractAutowireCapabaleBeanFactory類里(我是用ctrl+shift+alt+n找到的)的doCreateBean
先創(chuàng)造了一個bean原始對象,此時還沒有依賴注入

		BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
        }

        if (instanceWrapper == null) {
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }
        
        Object bean = instanceWrapper.getWrappedInstance();

然后將lambda表達式放入三級緩存中

        if (earlySingletonExposure) {
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
            }
			//放入三級緩存,這個lambda表達式是為了執(zhí)行aop生成代理對象用的,如果有aop操作,就會拿到代理對象出來
            this.addSingletonFactory(beanName, () -> {
                return this.getEarlyBeanReference(beanName, mbd, bean);
            });
        }

緊接著就是A的依賴填充

	this.populateBean(beanName, mbd, instanceWrapper);

在這個里面會走到一個getSingleton方法,也就是在緩存中找BService

	//allowEarlyReference是是否允許循環(huán)依賴
    @Nullable
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
            singletonObject = this.earlySingletonObjects.get(beanName);
            if (singletonObject == null && allowEarlyReference) {
                synchronized(this.singletonObjects) {
                	//一級緩存中找
                    singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) {
                    	//二級緩存中找
                        singletonObject = this.earlySingletonObjects.get(beanName);
                        if (singletonObject == null) {
                        	//三級緩存中找
                            ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
                            if (singletonFactory != null) {	//找到了
                            	//這里相當于上面圖文分析中BService在三級緩存中找到AService
                            	//直接用lambda表達式注冊,然后把他移動到二級緩存中
                                singletonObject = singletonFactory.getObject();
                                this.earlySingletonObjects.put(beanName, singletonObject);
                                this.singletonFactories.remove(beanName);
                            }
                        }
                    }
                }
            }
        }

        return singletonObject;
    }

但是顯然AService肯定不會找到,然后就會重新走到createBean,創(chuàng)建一個BService,與A一樣走到上述的getSingleton,這時會在三級緩存中找到A,然后注入

填充完成之后就會把BService放到一級緩存中,移除三級緩存中的B,然后結(jié)束

	exposedObject = this.initializeBean(beanName, exposedObject, mbd);

執(zhí)行完整個BService的創(chuàng)建,上面的A的依賴填充才會結(jié)束,然后A也執(zhí)行一遍exposedObject = this.initializeBean(beanName, exposedObject, mbd);這行代碼,A也結(jié)束。

結(jié)合圖文演示看代碼更容易理解捏文章來源地址http://www.zghlxwxcb.cn/news/detail-609256.html

到了這里,關(guān)于[Spring] 三級緩存解決循環(huán)依賴詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務器費用

相關(guān)文章

  • Spring使用三級緩存解決循環(huán)依賴?終于完全弄明白了

    文章閱讀前推薦 推薦先去看看源碼,源碼很短,但是對于我們在腦子里構(gòu)建一個完整思路很重要??雌饋矸浅:唵?,只需要雙擊shift,全局查找文件:AbstractAutowireCapableBeanFactory,找到550行左右的doCreateBean方法,重點看一下580行到600行這20行代碼就行,包含了三級緩存、屬性注

    2024年03月25日
    瀏覽(31)
  • Spring FrameWork從入門到NB -三級緩存解決循環(huán)依賴內(nèi)幕 (一)

    Spring FrameWork從入門到NB -三級緩存解決循環(huán)依賴內(nèi)幕 (一)

    循環(huán)依賴就是我依賴你、你依賴我,或者A依賴B、B依賴C、C依賴A…組成的錯綜復雜的依賴關(guān)系。 其實各種不同的依賴關(guān)系最終從邏輯上都可以演變?yōu)椋何乙蕾嚹?、你依賴我?循環(huán)依賴大致可以分為兩種情況: 屬性依賴:比如A對象有一個屬性B,B對象有屬性A。 構(gòu)造器依賴:

    2024年02月11日
    瀏覽(20)
  • Spring 為什么要用三級緩存來解決循環(huán)依賴(AOP),二級緩存不行嗎

    解決有代理對象的循環(huán)依賴不一定要三級緩存,用二級甚至一級也能解決,下面討論下Spring為什么選擇三級緩存這個方案。 Spring最開始是沒有三級緩存的,后面版本因為引入了AOP,有了代理對象,又因為存在循環(huán)依賴,為了保證依賴注入過程注入的是代理對象,且不完全打破

    2024年04月26日
    瀏覽(23)
  • SpringBoot 三級緩存解決循環(huán)依賴源碼分析

    SpringBoot 三級緩存解決循環(huán)依賴源碼分析

    在 SpringBoot 框架中,如果只存在兩級緩存,那么當發(fā)生循環(huán)依賴的時候可能存在異常的對象創(chuàng)建流程如下圖所示: 創(chuàng)建 A 的空白對象 a1 解析填充 A 對象的屬性,發(fā)現(xiàn)依賴的 B 對象未創(chuàng)建,則觸發(fā) B 對象創(chuàng)建 創(chuàng)建 B 對象過程中,填充對象屬性時發(fā)現(xiàn)依賴 A 對象,此時從緩存中

    2024年02月11日
    瀏覽(21)
  • Spring三級緩存詳解

    Spring三級緩存 是為了解決 對象間的循環(huán)依賴 問題。 A依賴B,B依賴A,這就是一個簡單的循環(huán)依賴。 我們來先看看三級緩存的源碼。 (1)查看“獲取Bean”的源碼,注意getSingleton()方法。 (2)“添加到第1級緩存”的源碼: (3)“添加到第3級緩存”的源碼: (4)“創(chuàng)建Be

    2024年02月07日
    瀏覽(29)
  • springIoc依賴注入循環(huán)依賴三級緩存

    springIoc依賴注入循環(huán)依賴三級緩存

    理論思想,原來的對象是由使用者來進行控制,有了spring之后,可以把整個對象交給spring來幫我們進行管理 依賴注入,把對應的屬性的值注入到具體的對象中,@autowired,populateBean完成屬性的注入 beanFactory,存儲對象,使用map結(jié)構(gòu)來存儲,在spring中一般存在三級緩存,singleton

    2024年01月16日
    瀏覽(20)
  • 一文詳解Spring Bean循環(huán)依賴

    一文詳解Spring Bean循環(huán)依賴

    一、背景 有好幾次線上發(fā)布老應用時,遭遇代碼啟動報錯,具體錯誤如下: 眨眼一看,這不就是Spring Bean循環(huán)依賴報錯嗎?腦海立馬閃過那些年為了進阿里面試時被死亡N連問的場景,那時我們都知道Spring已經(jīng)支持bean循環(huán)依賴,為啥我們的Springboot應用啟動時還報這個錯誤?帶

    2024年02月15日
    瀏覽(22)
  • Spring解決循環(huán)依賴

    Spring解決循環(huán)依賴

    目錄 什么是spring循環(huán)依賴 什么情況下循環(huán)依賴可以被處理? spring?如何解決循環(huán)依賴 創(chuàng)建A這個Bean的流程 答疑 疑問:在給B注入的時候為什么要注入一個代理對象? 初始化的時候是對A對象本身進行初始化,而容器中以及注入到B中的都是代理對象,這樣不會有問題嗎? 三級

    2024年02月22日
    瀏覽(24)
  • Spring解決循環(huán)依賴問題

    Spring解決循環(huán)依賴問題

    例如,就是A對象依賴了B對象,B對象依賴了A對象。(下面的代碼屬于 屬性的循環(huán)依賴 ,也就是初始化階段的循環(huán)依賴,區(qū)別與底下 構(gòu)造器的循環(huán)依賴 ) 問題來了: A Bean創(chuàng)建 —— 依賴了 B 屬性 ——? 觸發(fā) B Bean創(chuàng)建 ——? B 依賴了 A 屬性 ——? 需要 A Bean(但A Bean還在創(chuàng)建

    2024年02月12日
    瀏覽(25)
  • 【Spring】Spring的循環(huán)依賴以及解決方案

    【Spring】Spring的循環(huán)依賴以及解決方案

    ? Spring循環(huán)依賴指的是兩個或多個Bean之間相互依賴,形成一個環(huán)狀依賴的情況。通俗的說,就是A依賴B,B依賴C,C依賴A,這樣就形成了一個循環(huán)依賴的環(huán)。 ? Spring循環(huán)依賴通常會導致Bean無法正確地被實例化,從而導致應用程序無法正常啟動或者出現(xiàn)異常。因此,Spring循環(huán)

    2024年04月25日
    瀏覽(47)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包