欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

spring解決循環(huán)依賴的方案示例

 更新時間:2023年05月30日 11:07:21   作者:一葉飄零晉  
這篇文章主要介紹spring如何解決循環(huán)依賴,文中有相關的代碼示例給大家參考,對我們的學習或工作有一定的幫助,感興趣的同學可以借鑒閱讀

一、代碼

@Component
public class BService {
    @Autowired
    private AService aService;
    public void work(){
        System.out.println("bservice的工作");
    }
}
@Component
public class AService {
    @Autowired
    private  BService bService;
    public void work(){
        System.out.println("aservice的工作");
    }
}

二、AService 的bean創(chuàng)建過程

  • spring調(diào)用AService的無參構造方法實例化得到AService類得一個aService對象。
  • spring通過依賴注入填充aService中的bservice屬性。(先從單例池去找如果沒有就創(chuàng)建BService一直循環(huán)下去。。。。。
  • 填充其他屬性
  • 其他步驟
  • 加入單例池

所以產(chǎn)生循環(huán)依賴。

三、spring三級緩存

Spring三級緩存指的是Spring框架在管理Bean時所維護的三級緩存機制,其作用是提高Bean的創(chuàng)建效率和管理效率。

1、singletonObjects:該緩存中緩存的是完全創(chuàng)建好的單例Bean,即在第二級緩存(factoryBeanInstanceCache)中返回了完整的Bean實例。

2、earlySingletonObjects:該緩存中緩存的是未完全創(chuàng)建好的單例Bean實例(即只完成了實例化和初始化部分),主要為了解決循環(huán)依賴問題,即當一個Bean A依賴于Bean B,而Bean B又依賴于Bean A時,通過從earlySingletonObjects緩存中獲取到還未完成創(chuàng)建的Bean A實例,并將其注入到Bean B中,使得依賴注入操作可以順利完成。

3、singletonFactories:該緩存中緩存的是創(chuàng)建Bean的工廠,即BeanFactory的getObject()方法返回的Bean,也即Bean的創(chuàng)建過程。主要針對的是動態(tài)代理類型的對象。

四、三級緩存的使用過程

1、獲取singletonObjects緩存中的Bean實例,如果存在則直接返回Bean對象,否則繼續(xù)操作;
2、獲取earlySingletonObjects緩存中的Bean實例,如果存在則返回Bean對象,否則繼續(xù)操作。
3、獲取singletonFactories緩存中的Bean實例(即Bean的創(chuàng)建工廠),如果存在則通過工廠方法創(chuàng)建Bean實例并保存到earlySingletonObjects緩存中、從singletonFactories緩存中移除并返回Bean實例,否則繼續(xù)操作。

當一個Bean被創(chuàng)建完成并添加到singletonObjects緩存中后,其它依賴該Bean的Bean便可以通過getBean()方法直接獲取到完整的Bean實例,并完成依賴注入操作。

五、解決循環(huán)依賴

注意:
spring的依賴注入方式。分為setter注入和構造器注入。spring可以解決setter類型的構造注入,構造器形式的注入解決不掉。
spring的生命周期可以概括為四個大階段,實例化,屬性賦值,初始化,銷毀。

六、如果只有一級緩存能否解決依賴的問題

理論上可以,但是實際操作的時候會有問題,一級緩存和二級緩存的區(qū)分點,一個存放的是成品對象,一個存放的是半成品對象,當只有一個map的時候就意味著半成品對象和成品對象放到一起,半成品對象不能夠直接暴露給外部使用,因為會有空指針異常,所以如果非要用一個map存儲就要添加一個標識,來標注是半成品對象還是成品對象。如果按照這樣方式設計代碼,會很不優(yōu)雅,所以可以直接用兩個map來解決.不需要一個。

七、如果只有二級級緩存能否解決依賴的問題。

理論上可以,但是前提是在創(chuàng)建對象中不能有代理對象。

八、為什么必須要有三級緩存來解決循環(huán)依賴問題?為什么三級緩存可以解決帶有代理對象的循環(huán)依賴問題

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

不能

2、如果出現(xiàn)了同名的不同對象,應該怎么辦。 比如剛開始創(chuàng)建出原始對象,后續(xù)創(chuàng)建出了代理對象。

如果在創(chuàng)建過程中出現(xiàn)了同名的不同對象,那么后面創(chuàng)建的對象會覆蓋前面所創(chuàng)建的對象。

3、為什么要使用lambda表達式這樣的方式,或者為什么要加入三級緩存呢?
對象的屬性的賦值是在 populateBean方法完成的

代理對象的創(chuàng)建是在BeanPostProcessor的后置處理方法里面完成的。

public interface BeanPostProcessor {
	// 注意這個方法名稱關鍵的是before這個單詞
	Object postProcessBeforeInitialization(Object bean, String beanName) 
        throws BeansException;
    // 注意這個方法名稱關鍵的是after這個單詞
	Object postProcessAfterInitialization(Object bean, String beanName) 
        throws BeansException;
}

populateBean()要比BeanPostProcessor的后置方法先執(zhí)行也就是說

在進行對象屬性賦值的時候,代理對象還沒有創(chuàng)建出來,那么屬性的賦值只能是原始對象而在后續(xù)的步驟中又創(chuàng)建出了代理對象,此時的代理對象會有賦值的過程嗎?不會,所以會出現(xiàn)一個錯誤
this means that said other beans do not use the final version of the bean
就是說賦值是原始對象,而最終留下來的是代理對象,所以導致沒有使用最終版本的bean對象。

如何解決?
將代理對象的創(chuàng)建過程提前執(zhí)行,也就是說在進行對象賦值的時候必須要唯一性的確定出到底是原始對象還是代理對象,這個方法是在getEarlyBeanReference方法里執(zhí)行的,而getEarlyBeanReference是在populateBean方法的中調(diào)用的。

為什么使用lambda表達式

lambda相當于延遲執(zhí)行,因為此方法次方法并不會在方法的調(diào)用的時候立即執(zhí)行,而是在對象必須要進行屬性賦值的那一刻執(zhí)行,也就是說在對象賦值的的那一刻確定出了最終的bean對象。

總結:使用三級緩存本質(zhì)上是為了解決aop代理問題。當一個對象需要被代理的時候,在整個整個bean創(chuàng)建過程中,包含兩個對象,一個是普通對象,一個是代理生成代理對象,bean默認都是單例的,那么在整個過程中三級緩存在getEarlyBeanReference進行了一個判斷。如果不需要代理直接放回普通對象,如果需要代理就用代理對象替換。保證了bean的全局唯一性。所以能夠解決aop代理問題。

以上就是spring解決循環(huán)依賴的方案示例的詳細內(nèi)容,更多關于spring解決循環(huán)依賴的資料請關注腳本之家其它相關文章!

相關文章

  • 簡單實現(xiàn)Java web服務器

    簡單實現(xiàn)Java web服務器

    這篇文章主要為大家詳細介紹了簡單實現(xiàn)Java web服務器的詳細步驟,感興趣的小伙伴們可以參考一下
    2016-06-06
  • Java實現(xiàn)規(guī)則幾何圖形的繪制與周長面積計算詳解

    Java實現(xiàn)規(guī)則幾何圖形的繪制與周長面積計算詳解

    隨著計算機的發(fā)展,人們對圖形的計算要求會越來越高。在各行各業(yè)中的計算人員會對圖形的計算要有便利的要求,規(guī)則幾何圖形問題求解程序應運而生!本文將用Java編寫一個程序,可以實現(xiàn)規(guī)則幾何圖形的繪制與周長面積計算,感興趣的可以了解一下
    2022-07-07
  • Spring三級緩存解決循環(huán)依賴

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

    本文主要介紹了Spring三級緩存解決循環(huán)依賴,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • 詳解使用spring boot admin監(jiān)控spring cloud應用程序

    詳解使用spring boot admin監(jiān)控spring cloud應用程序

    這篇文章主要介紹了詳解使用spring boot admin監(jiān)控spring cloud應用程序,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • 基于Java快速實現(xiàn)一個簡單版的HashMap詳解

    基于Java快速實現(xiàn)一個簡單版的HashMap詳解

    這篇文章主要為大家詳細介紹了如何利用Java簡單實現(xiàn)一個底層數(shù)據(jù)結構為數(shù)組?+?鏈表的HashMap,不考慮鏈表長度超過8個時變?yōu)榧t黑樹的情況,需要的可以參考一下
    2023-02-02
  • java簡單實現(xiàn)數(shù)組的增刪改查方法

    java簡單實現(xiàn)數(shù)組的增刪改查方法

    這篇文章主要介紹了Java數(shù)組的增刪改查的示例,幫助大家更好的利用Java處理數(shù)據(jù),感興趣的朋友可以了解下,希望能給你帶來幫助
    2021-07-07
  • javafx實現(xiàn)五子棋游戲

    javafx實現(xiàn)五子棋游戲

    這篇文章主要為大家詳細介紹了javafx實現(xiàn)五子棋游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-05-05
  • 線程池之jdk1.8 Executors創(chuàng)建線程池的幾種方式

    線程池之jdk1.8 Executors創(chuàng)建線程池的幾種方式

    這篇文章主要介紹了線程池之jdk1.8 Executors創(chuàng)建線程池的幾種方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 深入了解Java中Synchronized關鍵字的實現(xiàn)原理

    深入了解Java中Synchronized關鍵字的實現(xiàn)原理

    synchronized是JVM的內(nèi)置鎖,基于Monitor機制實現(xiàn),每一個對象都有一個與之關聯(lián)的監(jiān)視器?(Monitor),這個監(jiān)視器充當了一種互斥鎖的角色,本文就詳細聊一聊Synchronized關鍵字的實現(xiàn)原理,需要的朋友可以參考下
    2023-06-06
  • Java多線程實現(xiàn)快速切分文件的程序

    Java多線程實現(xiàn)快速切分文件的程序

    這篇文章主要為大家詳細介紹了Java多線程實現(xiàn)快速切分文件的相關資料,感興趣的小伙伴們可以參考一下
    2016-06-06

最新評論