1.循環依存は何ですか?
円形の依存性は、実際には、互いに保持し、最終的に閉ループを形成するために2つ又は豆の二つ以上の円形の基準です。例えば、AがBに依存し、Bは、コードAに直接米国に依存します
ServiceBに依存クラスのサービスAを作成し、その後、順番にServiceBは、サービスAに依存します
@Component
public class ServiceA {
@Autowired
private ServiceB serviceb;
@Component
public class ServiceB {
@Autowired
private ServiceA servicea;
2.シングルトンスプリングオブジェクトの初期化は、3つのステップに分けられます。
-
createBeanInstanceは:インスタンス化、実際には、オブジェクトをインスタンス化するオブジェクトのコンストラクタメソッドを呼び出しています
-
充填特性は、このステップは、マルチ豆充填の性質に主に依存しています
-
InitializingBeanコールは同じオーバーINIT-方法の構成ファイル内のインターフェース、afterPropertiesSetメソッドまたはメソッド呼び出しを実装します。
-
実施形態初期上記単一豆から知ることができる:円形の依存は最初の2つのステップ、すなわち、コンストラクタ依存サイクルとサイクル依存分野で主に発生します。循環参照を解決するために持っている私たちは、だから、Cacheオブジェクトを考えるのは簡単ですので、春の単一のケースを解決するために、存在する必要があり、春の全ライフサイクル内のコンテナ、および1つのオブジェクトのみで、単一の場合のために、初期化プロセスから開始する必要があります3レベルのキャッシュを使用して循環依存、。
これは、2つの内部のばね特性は、内部singletonFactoriesとearlySingletonObjectsを使用伴うだろう、これらの二つの属性は以下のように定義されたクラスDefaultSingletonBeanRegistry、で定義されています。
ここでは、Beanの単一の例を作成するために、ステップスプリング、それを見て
SERVICEA次のを作成するための最初のステップ
入りのorg.springframework.beans.factory.support.AbstractBeanFactory#getBean方法
それが最初のサービスAで作成されるため、singletonFactoriesとearlySingletonObjectsとsingletonFactoriesは存在しません。だから、nullを返します。
そして、その後、サービスA BeanWrapper作成した抗セット、およびすることによって、この時間org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingletonFactoryを呼び出す我々singletonFactoriesがサービスA
そして、この時点で私たちのServiceBがロードされていない、そこSERVICEAプロパティServiceBため、プロパティは、populateBeanのサービスA満たされている呼び出し、その後、サービスAの必要性のServiceBは、ServiceBを作成する方法の春を呼ぶために行ってきました
私たちはその後、原因SERVICEAを依存順番にServiceBに、ServiceBのプロパティを埋めるために続けて、その後、すでにsingletonFactories内部のこの時間SERVICEAので、サービスAを作成するために移動し、我々は(この時点でserviceBプロパティがnullにある)1 SERVICEAを返し、そしてSERVICEAはearlySingletonObjectsに追加singletonFactories裏返しから削除しました。
何が良いそれがこれを行うのですか?私たちは、「フィールドのAまたはBオブジェクトのインスタンスに依存セッターと同様にして、オブジェクトのインスタンスに依存セッターフィールドBまたはA」この循環依存のケースを調べてみましょう。最初のステップは、最初の初期化を完了し、初期化の第2のステップは、オブジェクトB自身が依存見つけるその場合にsingletonFactories前進への暴露が、この時間は、(B)を取得しようとするために、Bを生成することが見出されていませんそのプロシージャを作成行く、Bは最初の一歩を初期化(完全に初期化されていないので、確かではない)ので、()、キャッシュsingletonObjectsを試す取得しよう、の対象に自身が依存見つけ、二次キャッシュearlySingletonObjectsを試してみてくださいBは、ObjectFactory.getObject(完全に初期化されませんが、大丈夫よりも良いされていませんが)でBテイクをオブジェクトaを得ることができるので、彼の初期の暴露によってObjectFactoryのため、3つのキャッシュsingletonFactoriesを試してみてください、(なかったです)その後、完全に初期化初期化フェーズが正常に完了を受け、2、3は、内のキャッシュsingletonObjectsに自分自身を配置します。Bを取得するため、この時点での復帰は、この時点ではAオブジェクトBは、その初期化フェーズ2と3、最終Aも完了し、初期化が正常に完了したことを取得するには、キャッシュsingletonObjectsは、さらに幸いに行き、オブジェクトへの参照は、A-Bは現在、ライブ対象が初期化を完了し保持します。
春には、「オブジェクトBの依存インスタンスの構成方法を、しかしBのコンストラクタは、Aがオブジェクトのインスタンスに依存し、」解決できない問題の種類なぜ確かに知っているとき、この原則を知っています!singletonFactories 3レベルのキャッシュを追加することの前提は、コンストラクタを実行することであるため、循環依存のコンストラクタは解決することはできません。
参考:https://blog.csdn.net/u010853261/article/details/77940767