欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

如何用Spring源碼解析循環(huán)依賴

本篇文章為大家展示了如何用Spring源碼解析循環(huán)依賴,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。

創(chuàng)新互聯(lián)公司是專業(yè)的從江網(wǎng)站建設(shè)公司,從江接單;提供網(wǎng)站制作、成都網(wǎng)站制作,網(wǎng)頁設(shè)計,網(wǎng)站設(shè)計,建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行從江網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊,希望更多企業(yè)前來合作!

我們今天接著聊聊,循環(huán)依賴的解決方案,即創(chuàng)建bean的ObjectFactory。

ObjectFactory

boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
        isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
    if (logger.isDebugEnabled()) {
        logger.debug("Eagerly caching bean '" + beanName +
                "' to allow for resolving potential circular references");
    }
    // 為避免后期循環(huán)依賴,可以在bean初始化完成前將創(chuàng)建實例的ObjectFactory加入工廠
    /**
     * getEarlyBeanReference(beanName, mbd, bean)方法:
     * 對bean再一次依賴引用,主要應(yīng)用SmartInstantiationAwareBeanPostProcessor
     * 其中我們熟知的AOP就是在這里將advice動態(tài)織入bean中,若沒有則直接返回bean,不做任何處理
     */
    addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

這段代碼不是很復(fù)雜,但是很多人不是太理解這段代碼的作用,而且,這段代碼僅從此函數(shù)中去理解也很難弄懂其中的含義,我們需要從全局的角度去思考 Spring 的依賴解決辦法。 earlySingletonExposure :從字面的意思理解就是提早曝光的單例,我們暫不定義它的學(xué)名叫什么,我們感興趣的是有哪些條件影響這個值。

  • mbd.isSingleton() :沒有太多可以解釋的,此 RootBeanDefinition 代表的是否是單例。

  • this.allowCircularReferences :是否允許循環(huán)依賴,很抱歉,并沒有找到在配置文件中如何配置,但是在 AbstractRefreshableApplicationContext 中提供了設(shè)置函數(shù),可以通過硬編碼的方式進(jìn)行設(shè)置或者可以通過自定義命名空間進(jìn)行配置,其中硬編碼的方式代碼如下。

ClassPathXmlApplicationContext bf = ClassPathXmlApplicationContext("aspectTest.xml" ); bt.setAllowBeanDefinitionOverriding(false);
  • isSingletonCurrentlylncreation(beanName) :該 bean 是否在創(chuàng)建中。在 Spring 中,會有個專門的屬性默認(rèn)為 DefaultSingletonBeanRegistry的 singletonsCurrentlylnCreation 來記錄 bean 的加載狀態(tài),在 bean 開始創(chuàng)建前會將 beanName 記錄在屬性中,在 bean 創(chuàng)建結(jié)束后會將 beanName 從屬性中移除。那么我們跟隨代碼一路走來可是對這個屬性的記錄并沒有多少印象,這個狀態(tài)是在哪里記錄的呢?不同 scope 的記錄位置并不一樣,我們以 singleton 為例,在 singleton 下記錄屬性的函數(shù)是在 DefaultSingletonBeanRegistry的 public Object getSingleton(String beanName, ObjectFactory singletonFactory)函數(shù)的 beforeSingletonCreation(beanName)和 afterSingletonCreation(beanName)中,在這兩段函數(shù)中分別this.singletonCurrentlylnCreation.add(beanName)與 this.singletonCurrentlylnCreation.remove(beanName)來進(jìn)行狀態(tài)的記錄與移除。

經(jīng)過以上分析我們了解變量 earl earlySingletonExposure 是否是單例、是否允許循環(huán)依賴、是否對應(yīng)的 bean 正在創(chuàng)建的條件的綜合。當(dāng)這 3 個條件都滿足時會執(zhí)行 addSingletonFactory操作,那么加入 SingletonFactory的作用是什么呢?又是在什么時候調(diào)用呢?

我們還是以最簡單的AB循環(huán)依賴為例,類A中含有屬性類B,而類B中又會含有屬性類A,那么初始化beanA的過程如下圖所示:

在創(chuàng)建 A 的時候首先會記錄類 A 所對應(yīng)的 beanName,并將beanA的創(chuàng)建工廠加入緩存中,而在對 A的屬性填充也就是調(diào)用populate方法的時候又會再一次的對 B 進(jìn)行遞歸創(chuàng)建。同樣的,因為在 B 中同樣存在 A 屬性,因此在實例化 B 的的 populate 方法中又會再次地初始化 A ,也就是圖形的最后,調(diào)用 getBean(A)。關(guān)鍵是在這里,有心的同學(xué)可以去找找這個代碼的實現(xiàn)方式,我們之前已經(jīng)講過,在這個函數(shù)中并不是直接去實例化 A ,而是先去檢測緩存中是否有已經(jīng)創(chuàng)建好的對應(yīng)的 bean ,或者是否已經(jīng)創(chuàng)建好的 ObjectFactory,而此時對于A的 ObjectFactory我們早已經(jīng)創(chuàng)建,所以便不會再去向后執(zhí)行,而是直接調(diào)用 ObjectFactory去創(chuàng)建 A 。這里最關(guān)鍵的是 ObjectFactory的實現(xiàn)。

/**
 * getEarlyBeanReference(beanName, mbd, bean)方法:
 * 對bean再一次依賴引用,主要應(yīng)用SmartInstantiationAwareBeanPostProcessor
 * 其中我們熟知的AOP就是在這里將advice動態(tài)織入bean中,若沒有則直接返回bean,不做任何處理
 */
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

其中g(shù)etEarlyBeanReference的代碼如下:

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
    Object exposedObject = bean;
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
            }
        }
    }
    return exposedObject;
}

在 getEarlyBeanReference 函數(shù)中并沒有太多的邏輯處理,或者說除了后處理器的調(diào)用外沒有別的處理工作,根據(jù)以上分析,基本可以理清 spring 處理循環(huán)依賴的解決辦法,在 B 中創(chuàng)建依賴 A 時通過 ObjectFactory 提供的實例化方法來中斷 A 中的屬性填充,使 B 中持有的 A 僅僅是剛剛初始化并沒有填充任何屬性的 A ,而這正初始化 A 的步驟還是在最開始創(chuàng)建 A 的時候進(jìn)行的,但是因為 A 與 B 中的 A 所表示的屬性地址是一樣的,所以在 A 中創(chuàng)建好的屬性填充自然可以通過 B 中的 A 獲取,這樣就解決了循環(huán)依賴的問題。

上述內(nèi)容就是如何用Spring源碼解析循環(huán)依賴,你們學(xué)到知識或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識儲備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

文章標(biāo)題:如何用Spring源碼解析循環(huán)依賴
網(wǎng)頁URL:http://aaarwkj.com/article42/igechc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站收錄、品牌網(wǎng)站設(shè)計、服務(wù)器托管、外貿(mào)網(wǎng)站建設(shè)、企業(yè)建站、網(wǎng)頁設(shè)計公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化
成年免费视频一区二区三区| 亚洲a∨乱码一区二区三区蜜臀 | 国产精品日韩精品在线| 97在线视频观看官网| 婷婷精品国产欧美精品亚洲| 99久久精彩免费视频| av免费观看日韩永久| 国产av白浆一区二区色爽黄| 国产91高清视频在线观看| 肥臀大屁股av在线播放| 亚洲永久免费黄色av| 未满十八禁止在线观看av| 丰满熟妇久久人妻同堂av| av毛片在线播放免费| 亚洲香蕉av在线一区二区三区| 亚洲一区二区三区日韩精品| 色综合亚洲一区二区小说| 日本又色又爽又黄又高潮| 亚洲欧美中文日韩二区一区| 日韩精品一二区电影| 久久国产精品必看狼人| 国产高清剧情在线观看| 少妇人妻精品一区二区三| 午夜福利院在线观看免费| 黄色大片免费在线观看| 日本老太老熟妇一级特黄| 亚洲国产精品一区二区av| 成人中文字幕日韩电影| 久久免费少妇高潮99精品| 全部网站免费在线观看等| 国产亚洲一区二区高清| 国产97成人亚洲综合在线| 亚洲av第一区综合激情久久久| 国产精品午夜福利91| 91一区二区亚洲嫩草| 免费高清视频一区二区在线观看 | 丝袜啪啪啪麻豆白虎内射| 日韩新片免费专区在线| 夫妻性生活免费看视频| 久久精品亚洲国产成人av| 91麻豆精品国产91久|