【ソースコード分析】Springのデザインパターン ~ContextとFactoryの関係~

フロー節約アシスタント

どちらのクラスも同じインターフェイスを実装していますが、一方のクラスが他方のクラスのインターフェイス実装を呼び出すことでインターフェイスを実装する、これが静的プロキシモードです(デコレータ モードとも言えますが、両者に大きな違いはありません)。この例では、AbstractBeanFactory と AnnotationConfigApplicationContext の両方が BeanFactory を実装していますが、BeanFactory に対する AnnotationConfigApplicationContext の getBean メソッドは
AbstractBeanFactory の BeanFactory の getBean メソッドの実装を呼び出すことによって実装されます。
したがって、Context と Factory の関係は次のようになります。Context は静的に Factory をプロキシし (または Context は Factory デコレータであり)、Context は Factory を保持します。

分析する

すべての Spring オブジェクトが getBean を通じて取得されることは誰もが知っています。私たちが最もよく遭遇するのは、IOC コンテナ (AnnotationConfigApplicationContext コンテキスト) を取得し、context.getBean(XXX.class);それを介して Bean を取得することです。このメソッドがどのように実装されているかを確認したい場合、大量の getBean メソッドが存在し、どれを確認すればよいのかわかりません。
賢い人なら、次のように考えるかもしれません。どの getBean が実際にオブジェクトを作成する作業を行っているのかわからないので、抽象インターフェイスにブレークポイントを設定している限り、IDEA は自然に特定の実装クラスを見つけるのに役立ちます。
したがって、コンテナ クラスを右クリックし、[図の表示] を選択します。IDEA は AnnotationConfigApplicationContext のクラス図を生成します。
ここに画像の説明を挿入します
インターフェイスを見るだけで、いわゆるコンテナが実際にリソース (ResourceLoader) をロードする機能と、 Bean (BeanFactory) を作成します。名前が示すように、コンテナーの getBean メソッド (AnnotationConfigApplicationContext) が BeanFactory から取得される必要があることがわかります。
このクラスを見つけて見てください:
ここに画像の説明を挿入します
確かに、まだ多くの getBean がありますが、多くてもこれら 5 つにブレークポイントを設定します。 getBeans、これは間違いなく私たちを壊すことになるでしょう。ブレークポイントを設定してデバッグを実行する:
ここに画像の説明を挿入します
ここには getBean メソッドもいくつかあり、公式もここに「BeanFactory インターフェースの実装」と明確に書いています。したがって、これらのメソッドは、Context によって実際に呼び出されるメソッドです。
しかし、ここで問題があります。これらの実装メソッドが配置されているクラス (AbstractBeanFactory) が、先ほど見たコンテナ (AnnotationConfigApplicationContext) の継承ツリーにありません。つまり、getBean の特定の実装はコンテナーには実装されません。
AbstractBeanFactory の継承ツリーを見ると、BeanFactory も継承していることがわかり、
ここに画像の説明を挿入します
少しややこしいのですが、Bean ファクトリが 2 つある可能性はありますか? Bean ファクトリが 2 つある場合、Context に設定されたブレークポイントが別の BeanFactory にブレークするのはなぜですか? どう考えても無理なので、実際に動作するBeanファクトリーは一つしかないはずです。AbstractBeanFactory が AnnotationConfigApplicationContext の継承ツリーに表示されない唯一の理由は、AnnotationConfigApplicationContext が AbstractBeanFactory (またはそのサブクラス) を保持しており、 AnnotationConfigApplicationContext が getBean と呼ばれるときに、AbstractBeanFactory の実装が実際に呼び出されるということです。
クラス図のプロパティを開くと、コンテキストが BeanFactory を保持していることがわかります (リソースローダーも保持しているため、コンテキストはこれら 2 つを組み合わせているだけです)。
ここに画像の説明を挿入します
次に、ソース コードをクリックすると、実際に呼び出されているのは Factory の getBean であることがわかります。
ここに画像の説明を挿入します
デザイン パターンを学習したことがある方なら、少し馴染みがあるかもしれません。両方のクラスが同じインターフェイスを実装していますが、一方のクラスは次の方法でインターフェイスを実装しています。もう一方を呼び出す クラスのインターフェースを実装することで実装される静的プロキシモードではないでしょうか(デコレータモードとも言えますが、両者に大きな違いはありません)
この例では、AbstractBeanFactory と AnnotationConfigApplicationContext の両方が BeanFactory を実装していますが、BeanFactory 上の AnnotationConfigApplicationContext の getBean メソッドは、AbstractBeanFactory の BeanFactory の getBean メソッドの実装を呼び出すことによって実装されます。
したがって、Context と Factory の関係は次のようになります。Context は静的に Factory をプロキシし (または Context は Factory デコレータであり)、Context は Factory を保持します。

Supongo que te gusta

Origin blog.csdn.net/weixin_45654405/article/details/127621250
Recomendado
Clasificación