偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Spring循環(huán)依賴詳解(看這篇就夠了)

開(kāi)發(fā) 前端
一級(jí)緩存(singletonObjects)也被稱為單例池,去存放已經(jīng)創(chuàng)建完成,并且屬性也注入完畢的對(duì)象,一般情況我們獲取bean都是從這里獲取的。

循環(huán)依賴

在探討Spring循環(huán)依賴的解決方式以前,我們先來(lái)回憶一下什么是循環(huán)依賴。

循環(huán)依賴:就是多個(gè)bean之間相互依賴,形成了一個(gè)閉環(huán)。

比如:A依賴于B、B依賴于A,如下圖所示:

圖片圖片

體現(xiàn)到代碼中為:

@Component
public class A{
   // 依賴B
   @Autowired
   private B b;
   public B getB() {
      return b;
   }
}


@Component
public class B {
   // 依賴A
   @Autowired
   private A a;
   public A getA() {
      return a;
   }
}

Spring的循環(huán)依賴過(guò)程:

  • 首先實(shí)例化A -> 屬性填充注入B -> B還沒(méi)有實(shí)例化;
  • 需要先進(jìn)行實(shí)例化B(A等待) -> 實(shí)例化B -> 注入A -> A實(shí)例化未完成,無(wú)法注入 -> 實(shí)例化B失敗 -> 實(shí)例化A失敗;

這樣反復(fù)就進(jìn)入了死循環(huán)了。

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

下面我還是用A -> B -> A的場(chǎng)景,我們按照過(guò)程一步步來(lái)分析,看一下Spring是如何解決循環(huán)依賴的。

第一步:首先是實(shí)例化A

圖片圖片

第二步:屬性注入B

執(zhí)行到屬性填充環(huán)節(jié)需要注入B,因?yàn)镾pring管理的bean默認(rèn)是單例的,為防止重復(fù)創(chuàng)建Spring會(huì)先去容器中查找B,如果查找不到再進(jìn)行創(chuàng)建。

如果Spring容器中是沒(méi)有B,需要先實(shí)例化B,流程和實(shí)例化一致,如下圖所示:

圖片圖片

第三步:屬性注入A

此時(shí)B也執(zhí)行到屬性填充的環(huán)節(jié)了,此時(shí)又需要注入A,此時(shí)還是會(huì)先去Spring容器中查找A,此時(shí)的A雖然沒(méi)在單例池中,但是因?yàn)樵趧?chuàng)建中并且也在三級(jí)緩存中了。

所以此時(shí)獲取A的流程就發(fā)生了變化,不再是直接創(chuàng)建,而是會(huì)從三級(jí)緩存中獲取A,如下圖所示:

圖片圖片

三級(jí)緩存存放的并不是bean對(duì)象,而是生成bean的ObjectFactory,然后放入二級(jí)緩存中,同時(shí)返回A進(jìn)行依賴注入。

第四步:初始化B

此時(shí),繼續(xù)執(zhí)行B的實(shí)例化, 并將B從正在創(chuàng)建列表移出 , 將B放入一級(jí)緩存,同時(shí)將B在二級(jí)緩存和三級(jí)緩存中刪,最后返回B。

圖片圖片

在B實(shí)例化完成并返回后,A的實(shí)例化流程也從等待著蘇醒繼續(xù)執(zhí)行,后續(xù)流程和B的完全一致。

圖片圖片

然后整個(gè)流程:A -> B -> A的場(chǎng)景就結(jié)束了。

這樣Spring通過(guò)三級(jí)緩存來(lái)解決循環(huán)依賴的,提前暴露的對(duì)象存放在三級(jí)緩存中,二級(jí)緩存存放過(guò)渡bean,一級(jí)緩存存放最終形態(tài)的bean。

Spring三級(jí)緩存

// 從上至下 分表代表這“三級(jí)緩存”
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); //一級(jí)緩存
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16); // 二級(jí)緩存
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); // 三級(jí)緩存

1.三級(jí)緩存(singletonFactories)

singletonFactories:?jiǎn)卫龑?duì)象工廠的cache,存放 bean 工廠對(duì)象,用于解決循環(huán)依賴。

2.二級(jí)緩存(earlySingletonObjects)

主要存放過(guò)渡bean,也就是三級(jí)緩存中ObjectFactory產(chǎn)生的對(duì)象。

提前曝光的單例對(duì)象的cache,存放原始的 bean 對(duì)象:尚未填充屬性,用于解決循環(huán)依賴。

3.一級(jí)緩存(singletonObjects)

也被稱為單例池,去存放已經(jīng)創(chuàng)建完成,并且屬性也注入完畢的對(duì)象,一般情況我們獲取bean都是從這里獲取的。

責(zé)任編輯:武曉燕 來(lái)源: mikechen的互聯(lián)網(wǎng)架構(gòu)
相關(guān)推薦

2019-08-16 09:41:56

UDP協(xié)議TCP

2021-09-30 07:59:06

zookeeper一致性算法CAP

2021-12-13 10:43:45

HashMapJava集合容器

2023-11-03 08:53:15

StrconvGolang

2021-05-07 07:52:51

Java并發(fā)編程

2022-03-29 08:23:56

項(xiàng)目數(shù)據(jù)SIEM

2022-10-17 09:01:09

JavaScripNode.js

2023-09-25 08:32:03

Redis數(shù)據(jù)結(jié)構(gòu)

2021-09-10 13:06:45

HDFS底層Hadoop

2023-10-04 00:32:01

數(shù)據(jù)結(jié)構(gòu)Redis

2023-11-07 07:46:02

GatewayKubernetes

2021-07-28 13:29:57

大數(shù)據(jù)PandasCSV

2017-03-30 22:41:55

虛擬化操作系統(tǒng)軟件

2021-07-12 12:20:08

Spring初始化方案

2025-02-18 16:00:00

SpringBoot支付Java

2023-11-22 07:54:33

Xargs命令Linux

2021-10-21 06:52:17

ZooKeeper分布式配置

2023-12-07 09:07:58

2018-09-26 11:02:46

微服務(wù)架構(gòu)組件

2021-04-11 08:30:40

VRAR虛擬現(xiàn)實(shí)技術(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)