日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
研究一下Spring里面的源碼,循環(huán)依賴你會(huì)么?

前幾天在阿粉CSDN上看一個(gè)文章,因?yàn)橐粋€(gè)Spring的問題,期望薪資三萬卻被生生的壓榨成了兩萬五,高于兩萬五人家都不要,讓我感覺到了Spring的強(qiáng)大,不學(xué)習(xí)Spring是會(huì)吃虧的,那么我們就從各種高頻面試來一點(diǎn)點(diǎn)深入吧。

成都創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于做網(wǎng)站、網(wǎng)站建設(shè)、武進(jìn)網(wǎng)絡(luò)推廣、微信小程序定制開發(fā)、武進(jìn)網(wǎng)絡(luò)營(yíng)銷、武進(jìn)企業(yè)策劃、武進(jìn)品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);成都創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供武進(jìn)建站搭建服務(wù),24小時(shí)服務(wù)熱線:13518219792,官方網(wǎng)址:www.cdcxhl.com

本文先從一個(gè)高頻面試題開始說起吧!阿粉在接下來會(huì)給大家?guī)砀鞣N關(guān)于Spring的知識(shí),希望大家能夠一起討論一下呦

Spring是怎么去解決循環(huán)依賴的

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

這個(gè)詞,阿粉聽到的時(shí)候,肯定和大家的反應(yīng)一樣的,循環(huán),依賴,那是不是 A 引用了 B ,而此時(shí) B 引用了 C,而 C 呢又引用了A,于是一個(gè)三角戀的關(guān)系出現(xiàn)了。

那么用代碼來表示的話,是怎么表示的呢?

 
 
 
 
  1. public class ClassTestA { 
  2.  
  3.     private ClassTestB classTestB; 
  4.  
  5.     public void a(){ 
  6.         classTestB.b(); 
  7.     } 
  8.  
  9.     public ClassTestB getClassTestB() { 
  10.         return classTestB; 
  11.     } 
  12.     private void setClassTestB(ClassTestB classTestB){ 
  13.         this.classTestB = classTestB; 
  14.     } 
  15.  
  16. public class ClassTestB { 
  17.  
  18.     private ClassTestC classTestC; 
  19.  
  20.     public void b(){ 
  21.         classTestC.c(); 
  22.     } 
  23.  
  24.     public ClassTestC getClassTestC() { 
  25.         return classTestC; 
  26.     } 
  27.     private void setClassTestC(ClassTestC classTestC){ 
  28.         this.classTestC = classTestC; 
  29.     } 
  30.  
  31. public class ClassTestC { 
  32.  
  33.     private ClassTestA classTestA; 
  34.  
  35.     public void c(){ 
  36.         classTestA.a(); 
  37.     } 
  38.  
  39.     public ClassTestA getClassTestA() { 
  40.         return classTestA; 
  41.     } 
  42.     private void setClassTestA(ClassTestA classTestA){ 
  43.         this.classTestA = classTestA; 
  44.     } 

2.循環(huán)依賴會(huì)出現(xiàn)什么問題

在阿粉的印象中,循環(huán)依賴最直接的問題就是會(huì)出現(xiàn)在對(duì)象的實(shí)例化上面,創(chuàng)建對(duì)象的時(shí)候,如果在Spring的配置中加入這種 A 依賴 B ,B 依賴 C,C 依賴 A 的話,那么最終創(chuàng)建 A 的實(shí)例對(duì)象的時(shí)候,會(huì)出現(xiàn)錯(cuò)誤。

而如果這種循環(huán)調(diào)用的依賴不去終結(jié)掉他的話,那么就相當(dāng)于一個(gè)死循環(huán),就像阿粉前幾天的在維護(hù)那個(gè) “十六年”之前的項(xiàng)目的時(shí)候,各種內(nèi)存溢出,表示內(nèi)心很壓抑呀。

而 Spring 中也將循環(huán)依賴的處理分成了不同的幾種情況,阿粉帶大家來看一下吧。

3.Spring循環(huán)依賴處理一 (構(gòu)造器循環(huán)依賴)

構(gòu)造器循環(huán)依賴的意思就是說,通過構(gòu)造及注入構(gòu)成的循環(huán)依賴,而這種依賴的話,是沒有辦法解決的,如果你敢強(qiáng)行依賴,不要意思,出現(xiàn)了你久違的異常 BeanCurrentlyInCreationException 出現(xiàn)這個(gè)異常的時(shí)候,就是表示循環(huán)依賴的問題。

相信大家出現(xiàn)異常的時(shí)候,在看不懂為什么的時(shí)候,第一時(shí)間,復(fù)制異常信息,放在百度,或者Google上面查詢一下,BeanCurrentlyInCreationException 放在百度上,一目了然。

而在 Spring 的配置文件中,如果這么配置 A ,B ,C 的循環(huán)依賴的時(shí)候,在創(chuàng)建 A 的時(shí)候,發(fā)現(xiàn),構(gòu)造器需要 B 類,然后去創(chuàng)建 B ,而創(chuàng)建 B 的時(shí)候,發(fā)現(xiàn)又需要 C ,然后去創(chuàng)建 C ,創(chuàng)建的時(shí)候發(fā)現(xiàn),竟然需要 A ,于是又掉頭回去了,于是就形成了一個(gè)閉環(huán),沒有辦法創(chuàng)建。

 
 
 
 
  1.  
  2.  
  3.    
  4.          
  5.    
  6.  
  7.    
  8.          
  9.    
  10.  
  11.    
  12.           
  13.    
  14.  

而在這種情況下,Spring實(shí)例化bean是通過ApplicationContext.getBean()方法來進(jìn)行的。如果要獲取的對(duì)象依賴了另一個(gè)對(duì)象,那么其首先會(huì)創(chuàng)建當(dāng)前對(duì)象,然后通過遞歸的調(diào)用ApplicationContext.getBean()方法來獲取所依賴的對(duì)象,最后將獲取到的對(duì)象注入到當(dāng)前對(duì)象中。而和剛才阿粉說的一樣,創(chuàng)建了閉環(huán),所以就沒有辦法創(chuàng)建了。

4.Spring循環(huán)依賴處理二(setter循環(huán)依賴)

setter循環(huán)注入是指通過setter注入方式構(gòu)成的循環(huán)依賴。而這種方式,是Spring可以進(jìn)行解決的。

而對(duì)于這種使用setter注入造成的依賴是通過Spring容器來提前暴露剛完成的構(gòu)造注入器的bean來完成的,但是這時(shí)候還沒有完成其他的步驟的時(shí)候。

這個(gè)時(shí)候我們就需要提前暴露出來一個(gè)單例的工廠方法,讓其他的bean來引用這個(gè)bean,

 
 
 
 
  1. addSingletonFactory(beanName,new ObjectFactory(){ 
  2.     public Object getObject() throws BeanException{ 
  3.         return getEarlyBeanReference(beanName,mbd,bean) 
  4.     } 
  5. }) 
  • Spring在創(chuàng)建 A 的時(shí)候,根據(jù)無參構(gòu)造來創(chuàng)建 A,并且暴露出 ObjectFactory 用來返回一個(gè)提前暴露好的 bean 然后再進(jìn)行setter來注入,

同理的B和C都是這個(gè)樣子的,這個(gè)時(shí)候就能完成setter注入了。

5.Spring循環(huán)依賴處理三(作用域循環(huán)依賴)

阿粉帶大家看一下這個(gè)配置方式

 
 
 
 
  1.  
  2.          
  3.      
  4.      
  5.              
  6.       
  7.       
  8.               
  9.        

而對(duì)于 “singleton”作用域的話,他是可以通過“setAllowCircularReference(false)”這種方式來進(jìn)制循環(huán)依賴的。

而且也是有缺陷的,這種方式只能解決單例作用域的bean循環(huán)依賴。

而Spring解決循環(huán)依賴的話,大家肯定會(huì)好奇,說是三級(jí)緩存,那么請(qǐng)找到你的Spring的源碼

 
 
 
 
  1. org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean 

里面代碼之前阿粉就說過,太多了,給大家發(fā)一下阿粉之前的鏈接,里面有詳細(xì)介紹Bean加載的所有過程。

文獻(xiàn)參考《Spring源碼深度解析》


標(biāo)題名稱:研究一下Spring里面的源碼,循環(huán)依賴你會(huì)么?
鏈接分享:http://www.5511xx.com/article/cdjocij.html