1. ホーム

[解決済み】SpringのApplicationContext.getBeanがダメだと言われる理由とは?

2022-03-30 03:40:28

質問

Springの一般的な質問をしてみました。 Spring Beansのオートキャスト を呼び出すと、複数の人から、Springの ApplicationContext.getBean() はできるだけ避けなければなりません。 それはなぜでしょうか?

Springで作成するように設定したBeanに、他にどのようにアクセスすればいいのでしょうか?

私は非ウェブアプリケーションでSpringを使用しており、共有の ApplicationContext オブジェクト LiorHが説明したように .

修正案

私は以下の答えを受け入れますが、以下はMartin Fowler氏による別の見解です。 Dependency InjectionとService Locatorのどちらが優れているかを議論しています。 (を呼び出すのと本質的に同じです)。 ApplicationContext.getBean() ).

その中で、ファウラー氏は、" サービスロケータでは、アプリケーションクラスはロケータへのメッセージによって明示的にそれ(サービス)を要求する。インジェクションでは、明示的な要求がなく、サービスがアプリケーションクラスの中に現れる-それゆえ、制御が逆転する。 制御の逆転は、フレームワークの一般的な機能ですが、それには代償が必要です。理解するのが難しく、デバッグするときに問題になりがちです。ですから、私は全体として、必要なとき以外は(制御の逆転を)避けることを好んでいます。これは、それが悪いということではなく、より単純な代替案よりもそれ自身を正当化する必要があると思うのです。 "。

どのように解決するのか?

他の質問のコメントにも書きましたが、Inversion of Controlの全体的な考え方は、以下の通りです。 どのクラスも、依存するオブジェクトをどのように取得するかは知りませんし、気にしません。 . これによって、ある依存関係の実装をどのようなものにするかをいつでも簡単に変更できるようになります。また、依存関係のモック実装を提供できるため、クラスのテストも容易になります。最後に、これによりクラスは よりシンプルに と、より中核的な責任に集中することができます。

呼び方 ApplicationContext.getBean() は、Inversion of Controlではありません! 与えられたBean名に対して設定された実装を変更するのはまだ簡単ですが、クラスはその依存関係を提供するためにSpringに直接依存しており、他の方法でそれを取得することはできません。テストクラスで独自のモック実装を作成し、それを自分で渡すことはできません。これは基本的に、依存性注入コンテナとしてのSpringの目的を破っています。

言いたい放題。

MyClass myClass = applicationContext.getBean("myClass");

の場合は、代わりに、例えばメソッドを宣言する必要があります。

public void setMyClass(MyClass myClass) {
   this.myClass = myClass;
}

そして、設定に

<bean id="myClass" class="MyClass">...</bean>

<bean id="myOtherClass" class="MyOtherClass">
   <property name="myClass" ref="myClass"/>
</bean>

Springは自動的に myClassmyOtherClass .

このようにすべてを宣言して、その根底には次のようなものがある。

<bean id="myApplication" class="MyApplication">
   <property name="myCentralClass" ref="myCentralClass"/>
   <property name="myOtherCentralClass" ref="myOtherCentralClass"/>
</bean>

MyApplication は最も中心的なクラスで、プログラム内の他のすべてのサービスに少なくとも間接的に依存しています。ブートストラップするとき、あなたの main メソッドを呼び出すと applicationContext.getBean("myApplication") を呼び出す必要はないはずです。 getBean() を使用します。