最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時間:2026年06月05日 08:48:21   作者:bingbingYang_88  
這篇文章主要介紹了springIoc依賴注入循環(huán)依賴三級緩存實踐,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

springIoc的理解,原理和實現(xiàn)

控制反轉(zhuǎn)

理論思想,原來的對象是由使用者來進(jìn)行控制,有了spring之后,可以把整個對象交給spring來幫我們進(jìn)行管理

依賴注入DI

依賴注入,把對應(yīng)的屬性的值注入到具體的對象中,@autowired,populateBean完成屬性的注入

容器

beanFactory,存儲對象,使用map結(jié)構(gòu)來存儲,在spring中一般存在三級緩存,singletonObjects存放完整的bean對象,earylySingletonObject,factoryObject,整個bean的生命周期,從創(chuàng)建初始化使用到銷毀的過程都是容器來管理的

分:

  1. 一般ioc容器的時候涉及到容器的創(chuàng)建過程(beanFactory,DefaultListableBeanFactory),向bean工廠中設(shè)置一些參數(shù)BeanPostProcessor,Aware接口的子類等等屬性
  2. 加載解析bean對象,準(zhǔn)備要創(chuàng)建的bean對象的定義對象 beanDefinition(xml或者注解的解析過程)
  3. beanFactoryPostProcessor的處理,此處是擴展點,PlaceHolder ConfigurSupport(占位符),ConfigurationClassProcessor.
  4. BeanPostProcessor的注冊功能,方便后續(xù)bean對象完成具體的擴展對象。
  5. 通過反射的方式將BeanDefinition對象實例化成具體的bean對象。
  6. bean對象的初始化過程(填充屬性,調(diào)用aware的子類方法,調(diào)用BeanPostProcessor前置處理方法,調(diào)用init-method方法,BeanPostProcessor的后置處理方法)
  7. 生成完整的bean對象,通過getBean方法可以直接獲取。

createBeanFactory,getBean,doGetBean,createBean,doCreateBean,createBeanInstance,populateBean

  1. 先通過createBeanFactory創(chuàng)建出一個Bean工廠(DeafaultListableBeanFactory)
  2. 開始循環(huán)創(chuàng)建對象,因為容器中的bean默認(rèn)都是單例的,所以通過getBean,doGetBean從容器中查找,找不到的話,通過createBean,doCreateBean方法,以反射的方式創(chuàng)建對象,一般情況下使用無參的構(gòu)造方法(getDeclaredConstruce,newInstance)
  3. 進(jìn)行對象的屬性填充populateBean
  4. 進(jìn)行其他的初始化操作initializingBean

描述一下bean的生命周期

  1. 實例化bean,反射的方式生成對象
  2. 填充bean的屬性:populateBean(),循環(huán)依賴的問題(三級緩存)
  3. 調(diào)用aware接口相關(guān)的方法:invokeAwareMethod(完成beanName可以獲取容器bean的名稱,BeanFactory獲取當(dāng)前bean factory這也可以調(diào)用容器的服務(wù),BeanClassLoader對象的屬性設(shè)置)
  4. 調(diào)用BeanPostProcessor中的前置方法:使用比較多的ApplicationContextPostProcessor設(shè)置ApplicationContext,Environment,ResourceLoader,EmbeddValueResolver等對象。
  5. 調(diào)用initmethod方法:invokeInitmethod(),判斷是否實現(xiàn)了IntialzingBean接口,如果有,調(diào)用afterPropertiesSet方法。
  6. 調(diào)用BeanPostProceessor的后置處理方法:spring的aop就是在此實現(xiàn)的,AbstractAutoProxyCreator注冊Destuction相關(guān)的回調(diào)接口。
  7. 通過getbean獲取完整對象
  8. 銷毀 判斷是否實現(xiàn)了DisposableBean接口 destroyMethod方法

循環(huán)依賴

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

第一種互相依賴:A 依賴 B,B 又依賴 A,它們之間形成了循環(huán)依賴

第二種三者之間的依賴 A依賴B,B依賴C,C依賴A

第三種是自我依賴:A依賴A形成了循環(huán)依賴

三級緩存

  1. singletonObjects:緩存某個beanName對應(yīng)的經(jīng)過了完整生命周期的bean
  2. earlySingletonObjects:緩存提前拿原始對象進(jìn)行了AOP之后得到的代理對象,原始對象還沒有進(jìn)行屬性注入和后續(xù)的BeanPostProcessor等生命周期
  3. singletonFactories:緩存的是一個ObjectFactory,主要用來去生成原始對象進(jìn)行了AOP之后得到的代理對象,在每個Bean的生成過程中,都會提前暴露一個工廠,這個工廠可能用到,也可能用不到,如果沒有出現(xiàn)循環(huán)依賴依賴本bean,那么這個工廠無用,本bean按照自己的生命周期執(zhí)行,執(zhí)行完后直接把本bean放入singletonObjects中即可,如果出現(xiàn)了循環(huán)依賴依賴了本bean,則另外那個bean執(zhí)行ObjectFactory提交得到一個AOP之后的代理對象(如果有AOP的話,如果無需AOP,則直接得到一個原始對象)。
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
	/** Cache of singleton objects: bean name to bean instance. */
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

	/** Cache of singleton factories: bean name to ObjectFactory. */
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

	/** Cache of early singleton objects: bean name to bean instance. */
	private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
}

能否把一級緩存和二級緩存合并,只保留一個map結(jié)構(gòu)來完成類似的功能?

理論上是可行的,一級緩存和二級緩存的value類型都是Object,都可以用來存放對象,只是對象的狀態(tài)不同而已,所以當(dāng)使用一個map的時候,只要給定具體的標(biāo)識就可以解決這個問題,也就是說設(shè)置對象的時候,在value中不再直接存放對象,而是對象加標(biāo)識位,比如0代表成品,1代表半成品,那么一個map就可以存儲成品對象和半成品對象了,但是雖然可以這么干,沒人會這么做,代碼不優(yōu)雅,而且每次在進(jìn)行對象的存或者放的時候都要判斷是否是成品對象,比較麻煩,直接用兩個map結(jié)構(gòu)解決即可

如果只有一級緩存和二級緩存,能否解決循環(huán)依賴的問題?

可以,但是有前提條件:沒有aop的配置或者不需要創(chuàng)建代理對象的時候,兩個map就可以解決循環(huán)依賴的問題

為什么三級緩存可以解決aop下的循環(huán)依賴問題?三級緩存到底有什么作用?

1,在同一個容器中,能否出現(xiàn)同名的不同對象?

不能,id是唯一標(biāo)識

2,在同一個容器中,按照標(biāo)準(zhǔn)的生命周期,先創(chuàng)建了原始對象,后續(xù)又創(chuàng)建了代理對象,那時會怎么辦?

當(dāng)創(chuàng)建了代理對象之后,應(yīng)該要使用代理對象的,但是原始對象已經(jīng)存在,那么應(yīng)該將原始對象給覆蓋掉。getEarlyBeanReference()方法執(zhí)行的邏輯是一樣的

3,三級緩存到底有什么作用,為什么存在代理對象的時候就要使用三級緩存呢?

在標(biāo)準(zhǔn)的bean的生命周期中,要先創(chuàng)建出原始對象,創(chuàng)建出原始對象之后要使用populateBean方法來完成屬性的賦值,此時賦值的對象是原始對象,因為代理對象還沒有創(chuàng)建,代理對象的創(chuàng)建步驟是在BeanPostProcessor的后置處理方法中,也就是說已經(jīng)完成賦值之后代理對象才創(chuàng)建出來,所以會報錯(this means that said other beans do not use the final version of the bean),如何解決這個問題呢?

需要將代理對象的創(chuàng)建前置,也就是說在對象賦值的那一刻,要唯一性的確定出到底是原始對象還是代理對象,所以會優(yōu)先把所有的bean都放到三級緩存中,在需要進(jìn)行對象賦值的時候,從三級緩存中取出lambda表達(dá)式,lambda表達(dá)式的執(zhí)行邏輯就是確定原始對象還是代理對象。如果是原始對象就賦值原始對象,如果是代理對象就賦值代理對象。

Spring中哪些情況下,不能解決循環(huán)依賴問題?

1,多例Bean通過setter注入的情況,不能解決循環(huán)依賴的問題。當(dāng)兩個多例Bean相互依賴并且使用 Setter 方法注入時,Spring容器無法解決循環(huán)依賴。這是因為在多例模式下,每次請求獲取一個新的Bean實例,Spring容器無法在創(chuàng)建Bean之前就確定依賴關(guān)系。

2,構(gòu)造器注入的bean情況,不能解決循環(huán)依賴的問題。循環(huán)依賴的產(chǎn)生:循環(huán)依賴通常在Bean的創(chuàng)建階段發(fā)生,而構(gòu)造器注入是在Bean創(chuàng)建之前發(fā)生的,因此無法通過構(gòu)造器注入的方式解決已經(jīng)發(fā)生的循環(huán)依賴。

3,設(shè)置了@DependsOn的Bean情況,不能解決循環(huán)依賴的問題。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • springboot 中異步任務(wù),定時任務(wù),郵件任務(wù)詳解

    springboot 中異步任務(wù),定時任務(wù),郵件任務(wù)詳解

    這篇文章主要介紹了springboot 與異步任務(wù),定時任務(wù),郵件任務(wù),本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09
  • 詳細(xì)講解Java中==與equals的區(qū)別對比

    詳細(xì)講解Java中==與equals的區(qū)別對比

    這篇文章主要為大家詳細(xì)介紹了Java中==與equals的區(qū)別對比,文中有詳細(xì)的代碼示例供大家參考,具有一定的參考價值,感興趣的同學(xué)可以參考閱讀下
    2023-09-09
  • Java中String類的常用方法總結(jié)

    Java中String類的常用方法總結(jié)

    java.lang.String?類代表字符串。Java程序中所有的字符串文字(例如"abc"?)都可以被看作是實現(xiàn)此類的實例。本文主要為大家介紹了String類的常用方法,需要的可以參考一下
    2022-11-11
  • SpringBoot?使用?spring.profiles.active?來區(qū)分不同環(huán)境配置實現(xiàn)

    SpringBoot?使用?spring.profiles.active?來區(qū)分不同環(huán)境配置實現(xiàn)

    很多時候,我們項目在開發(fā)環(huán)境和生產(chǎn)環(huán)境的配置是不一樣的,例如,數(shù)據(jù)庫配置,在開發(fā)的時候,我們一般用測試數(shù)據(jù)庫,而在生產(chǎn)環(huán)境,我們要用生產(chǎn)數(shù)據(jù)庫,這時候,我們可以利用?profile?在不同的環(huán)境下配置用不同的配置文件或者不同的配置,感興趣的可以了解一下
    2026-04-04
  • Java自動化實現(xiàn)將HTML轉(zhuǎn)換為Word

    Java自動化實現(xiàn)將HTML轉(zhuǎn)換為Word

    在日常的軟件開發(fā)和企業(yè)應(yīng)用中,我們經(jīng)常會遇到需要將動態(tài)生成的 HTML 內(nèi)容轉(zhuǎn)化為規(guī)范的 Word 文檔,本文將介紹如何利用 Java 輕松實現(xiàn) HTML 到 Word 的高效轉(zhuǎn)換,需要的可以了解下
    2025-10-10
  • 深入講解spring boot中servlet的啟動過程與原理

    深入講解spring boot中servlet的啟動過程與原理

    這篇文章主要給大家介紹了關(guān)于spring boot中servlet啟動過程與原理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-07-07
  • Java中文件讀寫操作與常用技巧分享

    Java中文件讀寫操作與常用技巧分享

    在 Java I/O 體系中,F(xiàn)ile 類是唯一代表磁盤文件本身的對象,而File 類定義了一些與平臺無關(guān)的方法來操作文件,所以下面我們一起來看看 File 類有哪些操作方法吧
    2023-06-06
  • mybatis 中 foreach collection的用法小結(jié)(三種)

    mybatis 中 foreach collection的用法小結(jié)(三種)

    這篇文章主要介紹了mybatis 中 foreach collection的用法小結(jié)(三種),需要的朋友可以參考下
    2017-10-10
  • Java中Map的computeIfAbsent方法詳解

    Java中Map的computeIfAbsent方法詳解

    這篇文章主要介紹了Java的Map中computeIfAbsent方法詳解,在jdk1.8中Map接口新增了一個computeIfAbsent方法,這是Map接口中的默認(rèn)實現(xiàn)該方法是首先判斷緩存Map中是否存在指定的key的值,如果不存在,會調(diào)用mappingFunction(key)計算key的value,需要的朋友可以參考下
    2023-11-11
  • 上傳自己的jar包到maven中央倉庫的快速操作方法

    上傳自己的jar包到maven中央倉庫的快速操作方法

    網(wǎng)絡(luò)上可以搜索到很多jar包到中央倉庫,但是都不是多適合自己的項目,于是自己動手寫個,本文檔通過sonatype上傳jar包至maven中央倉庫,Sonatype通過JIRA來管理OSSRH倉庫,具體實例代碼跟隨小編一起看看吧
    2021-08-08

最新評論

枞阳县| 白城市| 阜城县| 杭州市| 扎兰屯市| 讷河市| 永修县| 绵阳市| 永安市| 汉阴县| 定州市| 监利县| 叙永县| 汉中市| 邯郸市| 沛县| 招远市| 麻栗坡县| 嘉兴市| 大余县| 沅陵县| 龙山县| 台南县| 巴林右旗| 江山市| 莱西市| 明光市| 噶尔县| 鄯善县| 金沙县| 安阳县| 开原市| 扎兰屯市| 三都| 甘孜县| 湘潭县| 清苑县| 蓬莱市| 柳州市| 阜宁县| 汽车|