亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

Spring循環依賴的三種方式(推薦)

2024-07-13 10:17:27
字體:
來源:轉載
供稿:網友

引言:循環依賴就是N個類中循環嵌套引用,如果在日常開發中我們用new 對象的方式發生這種循環依賴的話程序會在運行時一直循環調用,直至內存溢出報錯。下面說一下spring是如果解決循環依賴的。

第一種:構造器參數循環依賴

Spring容器會將每一個正在創建的Bean 標識符放在一個“當前創建Bean池”中,Bean標識符在創建過程中將一直保持
在這個池中,因此如果在創建Bean過程中發現自己已經在“當前創建Bean池”里時將拋出
BeanCurrentlyInCreationException異常表示循環依賴;而對于創建完畢的Bean將從“當前創建Bean池”中清除掉。

首先我們先初始化三個Bean。

public class StudentA {    private StudentB studentB ;    public void setStudentB(StudentB studentB) {     this.studentB = studentB;   }    public StudentA() {   }      public StudentA(StudentB studentB) {     this.studentB = studentB;   } }
public class StudentB {    private StudentC studentC ;    public void setStudentC(StudentC studentC) {     this.studentC = studentC;   }      public StudentB() {   }    public StudentB(StudentC studentC) {     this.studentC = studentC;   } }
public class StudentC {    private StudentA studentA ;    public void setStudentA(StudentA studentA) {     this.studentA = studentA;   }    public StudentC() {   }     public StudentC(StudentA studentA) {     this.studentA = studentA;   } }

OK,上面是很基本的3個類,,StudentA有參構造是StudentB。StudentB的有參構造是StudentC,StudentC的有參構造是StudentA ,這樣就產生了一個循環依賴的情況,

我們都把這三個Bean交給Spring管理,并用有參構造實例化

<bean id="a" class="com.zfx.student.StudentA">   <constructor-arg index="0" ref="b"></constructor-arg> </bean> <bean id="b" class="com.zfx.student.StudentB">   <constructor-arg index="0" ref="c"></constructor-arg> </bean> <bean id="c" class="com.zfx.student.StudentC">   <constructor-arg index="0" ref="a"></constructor-arg> </bean>

下面是測試類:

public class Test {    public static void main(String[] args) {      ApplicationContext context = new ClassPathXmlApplicationContext("com/zfx/student/applicationContext.xml");      //System.out.println(context.getBean("a", StudentA.class));    }  }

  執行結果報錯信息為:

Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException:  
    Error creating bean with name 'a': Requested bean is currently in creation: Is there an unresolvable circular reference? 

如果大家理解開頭那句話的話,這個報錯應該不驚訝,Spring容器先創建單例StudentA,StudentA依賴StudentB,然后將A放在“當前創建Bean池”中,此時創建StudentB,StudentB依賴StudentC ,然后將B放在“當前創建Bean池”中,此時創建StudentC,StudentC又依賴StudentA, 但是,此時Student已經在池中,所以會報錯,,因為在池中的Bean都是未初始化完的,所以會依賴錯誤 ,(初始化完的Bean會從池中移除)

第二種:setter方式單例,默認方式

如果要說setter方式注入的話,我們最好先看一張Spring中Bean實例化的圖

 Spring,循環依賴

如圖中前兩步驟得知:Spring是先將Bean對象實例化之后再設置對象屬性的

修改配置文件為set方式注入:

<!--scope="singleton"(默認就是單例方式) --> <bean id="a" class="com.zfx.student.StudentA" scope="singleton">   <property name="studentB" ref="b"></property> </bean> <bean id="b" class="com.zfx.student.StudentB" scope="singleton">   <property name="studentC" ref="c"></property> </bean> <bean id="c" class="com.zfx.student.StudentC" scope="singleton">   <property name="studentA" ref="a"></property> </bean>

下面是測試類:

 public class Test {    public static void main(String[] args) {      ApplicationContext context = new ClassPathXmlApplicationContext("com/zfx/student/applicationContext.xml");      System.out.println(context.getBean("a", StudentA.class));    }  } 

打印結果為:

com.zfx.student.StudentA@1fbfd6 

為什么用set方式就不報錯了呢 ?

我們結合上面那張圖看,Spring先是用構造實例化Bean對象 ,此時Spring會將這個實例化結束的對象放到一個Map中,并且Spring提供了獲取這個未設置屬性的實例化對象引用的方法。   結合我們的實例來看,,當Spring實例化了StudentA、StudentB、StudentC后,緊接著會去設置對象的屬性,此時StudentA依賴StudentB,就會去Map中取出存在里面的單例StudentB對象,以此類推,不會出來循環的問題嘍、

下面是Spring源碼中的實現方法,。以下的源碼在Spring的Bean包中的DefaultSingletonBeanRegistry.Java類中

/** Cache of singleton objects: bean name --> bean instance(緩存單例實例化對象的Map集合) */   private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);      /** Cache of singleton factories: bean name --> ObjectFactory(單例的工廠Bean緩存集合) */   private final Map<String, ObjectFactory> singletonFactories = new HashMap<String, ObjectFactory>(16);      /** Cache of early singleton objects: bean name --> bean instance(早期的單身對象緩存集合) */   private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);      /** Set of registered singletons, containing the bean names in registration order(單例的實例化對象名稱集合) */   private final Set<String> registeredSingletons = new LinkedHashSet<String>(64);   /**    * 添加單例實例    * 解決循環引用的問題    * Add the given singleton factory for building the specified singleton    * if necessary.    * <p>To be called for eager registration of singletons, e.g. to be able to    * resolve circular references.    * @param beanName the name of the bean    * @param singletonFactory the factory for the singleton object    */   protected void addSingletonFactory(String beanName, ObjectFactory singletonFactory) {     Assert.notNull(singletonFactory, "Singleton factory must not be null");     synchronized (this.singletonObjects) {       if (!this.singletonObjects.containsKey(beanName)) {         this.singletonFactories.put(beanName, singletonFactory);         this.earlySingletonObjects.remove(beanName);         this.registeredSingletons.add(beanName);       }     }   }

第三種:setter方式原型,prototype

修改配置文件為:

<bean id="a" class="com.zfx.student.StudentA" <span style="color:#FF0000;">scope="prototype"</span>>     <property name="studentB" ref="b"></property>   </bean>   <bean id="b" class="com.zfx.student.StudentB" <span style="color:#FF0000;">scope="prototype"</span>>     <property name="studentC" ref="c"></property>   </bean>   <bean id="c" class="com.zfx.student.StudentC" <span style="color:#FF0000;">scope="prototype"</span>>     <property name="studentA" ref="a"></property>   </bean>

scope="prototype" 意思是 每次請求都會創建一個實例對象。兩者的區別是:有狀態的bean都使用Prototype作用域,無狀態的一般都使用singleton單例作用域。

測試用例:

public class Test {   public static void main(String[] args) {     ApplicationContext context = new ClassPathXmlApplicationContext("com/zfx/student/applicationContext.xml");     <strong>//此時必須要獲取Spring管理的實例,因為現在scope="prototype" 只有請求獲取的時候才會實例化對象</strong>     System.out.println(context.getBean("a", StudentA.class));   } }

打印結果:

Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'a': Requested bean is currently in creation: Is there an unresolvable circular reference?

為什么原型模式就報錯了呢 ?

對于“prototype”作用域Bean,Spring容器無法完成依賴注入,因為“prototype”作用域的Bean,Spring容
器不進行緩存,因此無法提前暴露一個創建中的Bean。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91久久在线观看| 国产精品无av码在线观看| 久久久精品国产一区二区| 国产精品私拍pans大尺度在线| 欧美制服第一页| 日本亚洲精品在线观看| 97香蕉久久超级碰碰高清版| 精品国产鲁一鲁一区二区张丽| 精品二区三区线观看| 亚洲在线视频福利| 欧美黑人国产人伦爽爽爽| 欧美激情videoshd| 久久午夜a级毛片| 亚洲国产精品成人精品| 亚洲性69xxxbbb| 日韩网站免费观看高清| 亚洲自拍小视频免费观看| 久久久久中文字幕2018| 中文字幕日韩在线观看| 国产亚洲日本欧美韩国| 亚洲在线观看视频| 91性高湖久久久久久久久_久久99| 色妞一区二区三区| 精品国产一区二区三区久久久| www.亚洲一区| 国内精品国产三级国产在线专| 97精品国产97久久久久久免费| 欧美劲爆第一页| 国产成人精品一区二区| 亚洲精品国精品久久99热一| 久久黄色av网站| 欧美成人合集magnet| 国产成人在线亚洲欧美| 57pao精品| 日韩精品欧美激情| 日韩精品有码在线观看| 亚洲免费小视频| 久久九九有精品国产23| 91精品久久久久久久久久| 欧美精品第一页在线播放| 91超碰中文字幕久久精品| 日韩精品高清视频| 久久亚洲精品国产亚洲老地址| 亚洲男人天堂手机在线| 久久在线视频在线| 欧美国产在线电影| 日韩性生活视频| 国产欧美中文字幕| 6080yy精品一区二区三区| 国产精品久久97| 国产午夜一区二区| 国产偷国产偷亚洲清高网站| 57pao国产成人免费| 欧美大片欧美激情性色a∨久久| 国产精品国内视频| 国产精品99久久久久久白浆小说| 一本大道亚洲视频| 精品久久久999| 亚洲国产精品久久91精品| 日韩不卡在线观看| 中文字幕成人精品久久不卡| 久久全国免费视频| 91日本在线视频| 这里精品视频免费| 中文字幕在线看视频国产欧美在线看完整| 中文字幕在线精品| 国产精品永久在线| 久久久久日韩精品久久久男男| 国产视频欧美视频| 亚洲精品成人av| 亚洲成年网站在线观看| 国产精自产拍久久久久久| 亚洲视频一区二区三区| 国产亚洲精品久久久久动| 欧美二区乱c黑人| 久久久欧美精品| 久久精品国产亚洲精品| 欧美日韩中文字幕日韩欧美| 日韩av在线导航| 亚洲娇小xxxx欧美娇小| 中文字幕精品在线| 成人免费视频网址| 亚洲成人精品久久久| 伊人伊成久久人综合网小说| 92国产精品视频| 久久久久久久久亚洲| 97视频在线观看视频免费视频| 欧美影院成年免费版| 日本精品视频在线播放| 久久青草精品视频免费观看| 国内精品视频一区| 日韩av中文在线| 中文字幕日韩综合av| 亚洲天堂第一页| 日韩视频中文字幕| 中国日韩欧美久久久久久久久| 亚洲国产精品电影在线观看| 国产噜噜噜噜噜久久久久久久久| 午夜精品一区二区三区在线播放| 91在线免费观看网站| 欧美福利视频在线| 国产精品一区久久久| 奇米4444一区二区三区| 美女999久久久精品视频| 亚洲三级免费看| 伊人伊成久久人综合网站| 亚洲午夜激情免费视频| 欧美大全免费观看电视剧大泉洋| 欧美在线xxx| 亚洲国产婷婷香蕉久久久久久| 国外成人免费在线播放| 97视频在线观看视频免费视频| 国产主播喷水一区二区| 91在线直播亚洲| 2019最新中文字幕| 久青草国产97香蕉在线视频| 久久久国产在线视频| 国产精品视频播放| 欧美成人精品在线观看| 97热精品视频官网| 国产精品一二三在线| 久久艳片www.17c.com| 久久久久久久网站| 国产成人+综合亚洲+天堂| 欧洲精品在线视频| 最近的2019中文字幕免费一页| 亚洲人成亚洲人成在线观看| 亚洲国产成人精品一区二区| 国产美女搞久久| 国产成人久久精品| 欧美黑人巨大精品一区二区| 欧美极品少妇xxxxⅹ裸体艺术| 免费成人高清视频| 一区二区三区视频免费在线观看| 欧美日韩精品国产| 亚洲精品自在久久| 国产成人精品免费久久久久| 欧美精品videosex性欧美| 欧美极品少妇xxxxx| 国产做受高潮69| 亚洲人午夜色婷婷| 日韩欧美在线视频日韩欧美在线视频| 黑丝美女久久久| 亚洲人成绝费网站色www| 国产成人在线亚洲欧美| 亚洲色图25p| 色综合色综合久久综合频道88| 国产成人亚洲综合青青| 日本一区二区在线免费播放| 亚洲一区二区免费在线| 成人羞羞国产免费| 亚洲精品影视在线观看| 91夜夜未满十八勿入爽爽影院| 国产精品美女免费视频| 亚洲国产精品va在看黑人| 色妞在线综合亚洲欧美| 久久人人看视频| 国产成人精品av在线| 美女扒开尿口让男人操亚洲视频网站| 91精品久久久久久久久久久久久| 欧美激情一区二区三区久久久| 97视频网站入口| 九九热这里只有精品6| 亚洲色在线视频|