はじめに:円形の依存関係は、nクラスのループネストされた参照です。新しいオブジェクトメソッドを使用して毎日の開発でこの循環依存関係が発生した場合、プログラムは、メモリがオーバーフローしてエラーを報告するまで、実行時にループを呼び出し続けます。循環依存関係を解決する場合は、春について話しましょう。
最初のタイプ:コンストラクターパラメーターサイクリック依存関係
スプリングコンテナは、各豆識別子を「現在のビーンプール」に配置し、ビーン識別子は作成プロセス中にこのプールに残ります。したがって、作成プロセス中にすでに「現在の豆プール」にいることがわかった場合、それは投げられます。
BeancurlentsincreationExceptionの例外は、循環依存性を示します。作成されたBeanは、「現在作成されているBean Pool」からクリアされます。
最初に3つの豆を初期化します。
パブリッククラスの学生{private studentb sudentb; public void setStudentB(StudentB StudentB){this.studentb = dustentB; } public sudenta(){} public desutenta(studentb desutentb){this.studentb = sudentb; }} Public Class StudentB {Private StudentC StudentC; public void setStudentc(StudentC StudentC){this.studentc = sudentc; } public Studentb(){} public sustentb(sustentc studentc){this.studentc = sudentc; }} Public Class StudentC {Private Studenta desutenta; public void setStudenta(dustenta desutenta){this.studenta = dustenta; } public studentc(){} public sudentc(desutent desutenta){this.studenta = dustenta; }}OK、上記は3つの非常に基本的なクラスです。 Studentaパラメーター構造はdustentBです。 StudentBのパラメーター構造はStudentCであり、StudentCのパラメーター構造はStudentaであり、これが循環依存関係の状況を作成します。
私たちは皆、これら3つの豆をバネの管理に手渡し、パラメーターコンストラクトでそれらをインスタンス化しました
<bean id = "a"> <constructor-arg index = "0" ref = "b"> </constructor-arg> </bean id = "b"> <constructor-arg index = "0" ref = "c"> </constructor-arg> </bean> <bean id = "c"> <construction-arg index = "> </bean
これがテストクラスです:
public class test {public static void main(string [] args){applicationContext Context = new ClassPathXMLApplicationContext( "com/zfx/suduent/applicationContext.xml"); //system.out.println(context.getbean("a "、sudentaa.class))); }}実行結果のエラーメッセージは次のとおりです。
原因:org.springframework.beans.factory.beancurlentyincreationexception:
「A」という名前のBeanの作成エラー:リクエストされたBeanは現在作成中です:解決できない円形の参照はありますか?
最初に文を理解している場合は、このエラーを報告することに驚かないでください。スプリングコンテナは、最初にシングルトンの学生を作成します。 StudentaはStudentBに依存し、「現在のBeanプール」にAを配置します。現時点では、StudentBが作成され、StudentBはStudentCに依存し、Bは「現在のBeanプール」に配置されます。現時点では、StudentCが作成され、StudentCはStudentaに依存します。ただし、現時点では、学生はすでにプールにいるため、エラーが報告されます。プール内のすべての豆は初期化されていないため、エラーに依存します。 (初期化された豆はプールから削除されます)
2番目のタイプ:セッターメソッドシングルトン、デフォルトメソッド
セッターの注入についてお話したい場合は、春にインスタンス化する豆の写真を見た方が良いでしょう
図の最初の2つのステップに示されているように、SpringはBeanオブジェクトをインスタンス化し、オブジェクトプロパティを設定します。
構成ファイルを変更して、セットモードに挿入します。
<! - scope = "singleton"(デフォルトはシングルトンメソッド) - > <bean id = "a" scope = "singleton"> <property name = "desudentb" ref = "b"> </property> </bean> <bean id = "b" scope = "singleton"> <propertion name = "desudentc" ref = " scope = "singleton"> <プロパティname = "studenta" ref = "a"> </property> </bean>
これがテストクラスです:
public class test {public static void main(string [] args){applicationContext Context = new ClassPathXMLApplicationContext( "com/zfx/suduent/applicationContext.xml"); system.out.println(context.getBean( "a"、dustenta.class)); }}印刷の結果は次のとおりです。
com.zfx.student.studenta@1fbfd6
セットメソッドを使用して間違いを報告してみませんか?
上の写真を見てみましょう。 Springは、コンストラクトを使用してBeanオブジェクトを最初にインスタンス化します。この時点で、Springはインスタンス化されたオブジェクトをマップに入れ、Springは未定の属性を持つインスタンス化されたオブジェクト参照を取得する方法を提供します。この例に基づいて、SpringがStudenta、StudentB、およびStudentCをインスタンス化すると、オブジェクトプロパティが設定されます。現時点では、StudentaはStudentBに依存し、マップ内のSingleton StudentBオブジェクトを取り出します。そのため、ループの問題はありません。
以下は、スプリングソースコードの実装方法です。次のソースコードは、SpringのBeanパッケージのDefaultingletonbeanregistry.javaクラスにあります
/ **シングルトンオブジェクトのキャッシュ:Bean Name-> Bean Instance(シングルトンがインスタンス化されたオブジェクトをキャッシュするマップコレクション) / **シングルトン工場のキャッシュ:Bean Name-> ObjectFactory(Singleton Factory Bean Cache Collection)*/ Private Final Map <String、ObjectFactory> SingletonFactory = new Hashmap <String、objectFactory>(16); / **初期のシングルトンオブジェクトのキャッシュ:Bean Name-> Bean Instance*/ Private Final Map <String、Object> EarlySingletonObjects = new Hashmap <String、object>(16); / **登録済みのシングルトンのセット、登録順に豆名を含む*/プライベート最終セット<string>登録済みgedsinglotons = new linkedhashset <string>(64); /*** Singletonインスタンスを追加*円形の参照の問題を解決します*指定されたSingleton Factoryを追加して、必要に応じて指定されたSingleton*を構築します。 * <p>シングルトンの熱心な登録のために呼び出されると、たとえば、循環参照を解決できるようにすることができます。 * @param beanname beanの名前 * @param singletonfactory singleton objectの工場 */保護されたvoid addsingletonfactory(string beanname、objectactory singletonfactory)同期(this.singletonobjects){if(!this.singletonobjects.containskey(beanname)){this.singletonfactories.put(beanname、singletonfactory); this.eallysingletonobjects.remove(beanname); this.registeredsingletons.add(beanname); }}3番目のタイプ:セッタープロトタイプ、プロトタイプ
構成ファイルを以下に変更します。
<bean id = "a" <span style = "color:#ff0000;"> scope = "prototype" </span >> <プロパティname = "desudentb" ref = "b"> </property> </bean> <bean id = "b" <span style = "color:#ff0000;"> scope = "" property name "</span </</bied =" ""> <bean id = "c" <span style = "color:#ff0000;"> scope = "prototype" </span >> <プロパティname = "studentc" ref = "c"> </property> </bean> <bean id = "c" <span style = "color:#ff0000;"> scope = "" property name "</span </vied =">
scope = "Prototype"とは、要求するたびにインスタンスオブジェクトが作成されることを意味します。 2つの違いは次のとおりです。ステートレスは通常、シングルトンシングルトンスコープを使用しているのに対し、ステートレスはプロトタイプスコープを使用します。
テストケース:
public class test {public static void main(string [] args){applicationContext Context = new ClassPathXMLApplicationContext( "com/zfx/suduent/applicationContext.xml"); <strong> //この時点で、Spring Managedのインスタンスを取得する必要があります。これは、Scope = "Prototype"が</strong> system.out.println(context.getbean( "a"、 "a"、sudenta.class))を取得することを要求する場合にのみオブジェクトをインスタンス化するためです。 }}印刷結果:
原因:org.springframework.beans.factory.beancurllingtingincreationexception: 'a' 'a'でbeanを作成するエラー:リクエストされたbeanは現在作成中です。
プロトタイプモデルが間違っているのはなぜですか?
「プロトタイプ」スコープ豆の場合、スプリング容器は「プロトタイプ」スコープ豆の豆をキャッシュしないため、スプリング容器は依存噴射を完了できません。したがって、作成された豆は事前に露出することはできません。
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。