国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務(wù)器之家 - 編程語言 - JAVA教程 - 淺談Spring解決循環(huán)依賴的三種方式

淺談Spring解決循環(huán)依賴的三種方式

2021-02-06 12:25學(xué)習(xí)園 JAVA教程

本篇文章主要介紹了淺談Spring循環(huán)依賴的三種方式,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

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

第一種:構(gòu)造器參數(shù)循環(huán)依賴

表示通過構(gòu)造器注入構(gòu)成的循環(huán)依賴,此依賴是無法解決的,只能拋出beancurrentlyin creationexception異常表示循環(huán)依賴。

如在創(chuàng)建testa類時,構(gòu)造器需要testb類,那將去創(chuàng)建testb,在創(chuàng)建testb類時又發(fā)現(xiàn)需要testc類,則又去創(chuàng)建testc,最終在創(chuàng)建testc時發(fā)現(xiàn)又需要testa,從而形成一個環(huán),沒辦法創(chuàng)建。

spring容器會將每一個正在創(chuàng)建的bean 標(biāo)識符放在一個“當(dāng)前創(chuàng)建bean池”中,bean標(biāo)識符在創(chuàng)建過程中將一直保持
在這個池中,因此如果在創(chuàng)建bean過程中發(fā)現(xiàn)自己已經(jīng)在“當(dāng)前創(chuàng)建bean池”里時將拋出
beancurrentlyincreationexception異常表示循環(huán)依賴;而對于創(chuàng)建完畢的bean將從“當(dāng)前創(chuàng)建bean池”中清除掉。

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class studenta {
 
 private studentb studentb ;
 
 public void setstudentb(studentb studentb) {
 this.studentb = studentb;
 }
 
 public studenta() {
 }
 
 public studenta(studentb studentb) {
 this.studentb = studentb;
 }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class studentb {
 
 private studentc studentc ;
 
 public void setstudentc(studentc studentc) {
 this.studentc = studentc;
 }
 
 public studentb() {
 }
 
 public studentb(studentc studentc) {
 this.studentc = studentc;
 }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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有參構(gòu)造是studentb。studentb的有參構(gòu)造是studentc,studentc的有參構(gòu)造是studenta ,這樣就產(chǎn)生了一個循環(huán)依賴的情況,我們都把這三個bean交給spring管理,并用有參構(gòu)造實例化

?
1
2
3
4
5
6
7
8
9
<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>

下面是測試類:

?
1
2
3
4
5
6
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));
 }
}

執(zhí)行結(jié)果報錯信息為:

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? 

如果大家理解開頭那句話的話,這個報錯應(yīng)該不驚訝,spring容器先創(chuàng)建單例studenta,studenta依賴studentb,然后將a放在“當(dāng)前創(chuàng)建bean池”中,此時創(chuàng)建studentb,studentb依賴studentc ,然后將b放在“當(dāng)前創(chuàng)建bean池”中,此時創(chuàng)建studentc,studentc又依賴studenta, 但是,此時student已經(jīng)在池中,所以會報錯,,因為在池中的bean都是未初始化完的,所以會依賴錯誤 ,(初始化完的bean會從池中移除)

第二種:setter方式單例,默認(rèn)方式

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

淺談Spring解決循環(huán)依賴的三種方式

如圖中前兩步驟得知:spring是先將bean對象實例化之后再設(shè)置對象屬性的

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

?
1
2
3
4
5
6
7
8
9
10
<!--scope="singleton"(默認(rèn)就是單例方式) -->
<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>

下面是測試類:

?
1
2
3
4
5
6
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));
 }
}

打印結(jié)果為:

com.zfx.student.studenta@1fbfd6 

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

我們結(jié)合上面那張圖看,spring先是用構(gòu)造實例化bean對象 ,此時spring會將這個實例化結(jié)束的對象放到一個map中,并且spring提供了獲取這個未設(shè)置屬性的實例化對象引用的方法。   結(jié)合我們的實例來看,,當(dāng)spring實例化了studenta、studentb、studentc后,緊接著會去設(shè)置對象的屬性,此時studenta依賴studentb,就會去map中取出存在里面的單例studentb對象,以此類推,不會出來循環(huán)的問題嘍、

下面是spring源碼中的實現(xiàn)方法,。以下的源碼在spring的bean包中的defaultsingletonbeanregistry.java類中

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/** 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);
 /**
 * 添加單例實例
 * 解決循環(huán)引用的問題
 * 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

對于"prototype"作用域bean,spring容器無法完成依賴注入,因為spring容器不進(jìn)行緩存"prototype"作用域的bean,因此無法提前暴露一個創(chuàng)建中的bean。

修改配置文件為:

?
1
2
3
4
5
6
7
8
9
<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" 意思是 每次請求都會創(chuàng)建一個實例對象。兩者的區(qū)別是:有狀態(tài)的bean都使用prototype作用域,無狀態(tài)的一般都使用singleton單例作用域。

測試用例:

?
1
2
3
4
5
6
7
public class test {
 public static void main(string[] args) {
 applicationcontext context = new classpathxmlapplicationcontext("com/zfx/student/applicationcontext.xml");
 <strong>//此時必須要獲取spring管理的實例,因為現(xiàn)在scope="prototype" 只有請求獲取的時候才會實例化對象</strong>
 system.out.println(context.getbean("a", studenta.class));
 }
}

打印結(jié)果:

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容
器不進(jìn)行緩存,因此無法提前暴露一個創(chuàng)建中的bean。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:http://blog.csdn.net/u010644448/article/details/59108799

延伸 · 閱讀

精彩推薦
  • JAVA教程基于Spring + Spring MVC + Mybatis 高性能web構(gòu)建實例詳解

    基于Spring + Spring MVC + Mybatis 高性能web構(gòu)建實例詳解

    這篇文章主要介紹了基于Spring + Spring MVC + Mybatis 高性能web構(gòu)建實例詳解,需要的朋友可以參考下...

    夢想合伙人2262020-09-12
  • JAVA教程java之super關(guān)鍵字用法實例解析

    java之super關(guān)鍵字用法實例解析

    這篇文章主要介紹了java之super關(guān)鍵字用法實例解析,較為詳細(xì)的分析了super關(guān)鍵字的用法及內(nèi)存分布,需要的朋友可以參考下 ...

    shichen20143932019-12-01
  • JAVA教程springAOP的三種實現(xiàn)方式示例代碼

    springAOP的三種實現(xiàn)方式示例代碼

    這篇文章主要介紹了springAOP的三種實現(xiàn)方式,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考...

    易水寒的博客2522020-07-21
  • JAVA教程25個最好的免費Eclipse插件

    25個最好的免費Eclipse插件

    這篇文章為大家分享了25個讓Java程序員更高效的Eclipse插件,感興趣的朋友可以參考一下 ...

    Sunshine_lily5952020-03-10
  • JAVA教程java計算集合對稱差的示例代碼

    java計算集合對稱差的示例代碼

    本篇文章主要介紹了java計算集合對稱差的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧...

    xixicat4302020-12-24
  • JAVA教程Java 正則表達(dá)式詳細(xì)介紹

    Java 正則表達(dá)式詳細(xì)介紹

    本文主要介紹 Java 正則表達(dá)式的內(nèi)容,這里整理了Java 正則表達(dá)式的相關(guān)資料,并詳細(xì)介紹,附有代碼示例,有興趣的小伙伴可以參考下...

    kdnuggets1992020-06-10
  • JAVA教程java微信公眾號開發(fā)案例

    java微信公眾號開發(fā)案例

    這篇文章主要為大家詳細(xì)介紹了java微信公眾號開發(fā)案例,如何接入公眾號,訂閱號怎么樣接收消息,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    偉雪無痕3862020-07-06
  • JAVA教程詳解Java中@Override的作用

    詳解Java中@Override的作用

    這篇文章主要介紹了詳解Java中@Override的作用的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解這部分內(nèi)容,需要的朋友可以參考下...

    _QING_FENG5972021-01-19
主站蜘蛛池模板: 日韩视频在线一区二区 | 亚洲处破女 | www中文字幕在线观看 | 午夜视频在线播放 | 成年人免费在线看网站 | 中文字幕一区二区三区在线视频 | 国产精品国产三级国产aⅴ中文 | 午夜剧场在线免费观看 | 羞羞视频免费观看网站 | 爱色av入口| 国产午夜精品一区二区三区嫩草 | 国产精品久久久久久久久久久免费看 | 日韩天堂| 国产日韩一级片 | 日韩高清一区二区 | 极品国产粉嫩av免费观看 | 黄色影院 | 一区二区三区在线观看视频 | 九色av| 日韩精品三区 | 亚洲视频在线观看网址 | 成人午夜电影在线观看 | 国产一区二区三区免费视频 | 日韩一区二区三区视频 | 国产一级纯肉体一级毛片 | 99re免费视频精品全部 | 精品无码久久久久久国产 | 成人av在线网站 | 欧美中文在线 | 中日韩黄色大片 | 久久女人网 | 在线一二三区 | 欧美日韩中文 | 久久av网 | 亚洲狠狠爱 | 国产精品日本一区二区不卡视频 | 操操操干干干 | 日韩av一区二区在线观看 | 中文字幕在线观看 | 成人激情免费视频 | 亚洲久久|