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

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

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

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

控制反轉(zhuǎn)

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

依賴注入DI

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

容器

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

分:

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

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

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

描述一下bean的生命周期

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

循環(huán)依賴

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

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

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

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

三級(jí)緩存

  1. singletonObjects:緩存某個(gè)beanName對(duì)應(yīng)的經(jīng)過了完整生命周期的bean
  2. earlySingletonObjects:緩存提前拿原始對(duì)象進(jìn)行了AOP之后得到的代理對(duì)象,原始對(duì)象還沒有進(jìn)行屬性注入和后續(xù)的BeanPostProcessor等生命周期
  3. singletonFactories:緩存的是一個(gè)ObjectFactory,主要用來去生成原始對(duì)象進(jìn)行了AOP之后得到的代理對(duì)象,在每個(gè)Bean的生成過程中,都會(huì)提前暴露一個(gè)工廠,這個(gè)工廠可能用到,也可能用不到,如果沒有出現(xiàn)循環(huán)依賴依賴本bean,那么這個(gè)工廠無用,本bean按照自己的生命周期執(zhí)行,執(zhí)行完后直接把本bean放入singletonObjects中即可,如果出現(xiàn)了循環(huán)依賴依賴了本bean,則另外那個(gè)bean執(zhí)行ObjectFactory提交得到一個(gè)AOP之后的代理對(duì)象(如果有AOP的話,如果無需AOP,則直接得到一個(gè)原始對(duì)象)。
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);
}

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

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

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

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

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

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

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

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

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

3,三級(jí)緩存到底有什么作用,為什么存在代理對(duì)象的時(shí)候就要使用三級(jí)緩存呢?

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

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

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

1,多例Bean通過setter注入的情況,不能解決循環(huán)依賴的問題。當(dāng)兩個(gè)多例Bean相互依賴并且使用 Setter 方法注入時(shí),Spring容器無法解決循環(huán)依賴。這是因?yàn)樵诙嗬J较?,每次請求獲取一個(gè)新的Bean實(shí)例,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é)

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

相關(guān)文章

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

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

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

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

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

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

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

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

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

    Java自動(dòng)化實(shí)現(xiàn)將HTML轉(zhuǎn)換為Word

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

    深入講解spring boot中servlet的啟動(dòng)過程與原理

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

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

    在 Java I/O 體系中,F(xiàn)ile 類是唯一代表磁盤文件本身的對(duì)象,而File 類定義了一些與平臺(tái)無關(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接口新增了一個(gè)computeIfAbsent方法,這是Map接口中的默認(rèn)實(shí)現(xiàn)該方法是首先判斷緩存Map中是否存在指定的key的值,如果不存在,會(huì)調(diào)用mappingFunction(key)計(jì)算key的value,需要的朋友可以參考下
    2023-11-11
  • 上傳自己的jar包到maven中央倉庫的快速操作方法

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

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

最新評(píng)論

临澧县| 赣榆县| 广东省| 徐水县| 西贡区| 新和县| 广丰县| 玉溪市| 静宁县| 德惠市| 武清区| 天全县| 益阳市| 深圳市| 固始县| 彝良县| 阳西县| 金寨县| 阳山县| 东兴市| 镇雄县| 龙泉市| 大丰市| 临颍县| 罗定市| 天津市| 宜兴市| 册亨县| 邹平县| 桦南县| 隆回县| 安远县| 内丘县| 玉田县| 衡阳市| 巫溪县| 定州市| 广宗县| 湖南省| 沈丘县| 乐陵市|