1. 序章

このチュートリアルでは、 BeanFactory.getBean()メソッドのさまざまなバリエーションについて説明します。

簡単に言えば、メソッドの名前も示すように、 this は、SpringコンテナーからBeanインスタンスを取得する役割を果たします。

2. SpringBeansのセットアップ

まず、テスト用にいくつかのSpringBeanを定義しましょう。 Springコンテナにbean定義を提供する方法はいくつかありますが、この例では、アノテーションベースのJava構成を使用します。

@Configuration
class AnnotationConfig {

    @Bean(name = {"tiger", "kitty"})
    @Scope(value = "prototype")
    Tiger getTiger(String name) {
        return new Tiger(name);
    }

    @Bean(name = "lion")
    Lion getLion() {
        return new Lion("Hardcoded lion name");
    }

    interface Animal {}
}

2つのBeanを作成しました。 Lionにはデフォルトのシングルトンスコープがあります。 Tigerは明示的にプロトタイプスコープに設定されています。 さらに、今後のリクエストで使用するbeanごとに名前を定義したことに注意してください。

3. getBean() API

BeanFactory は、次のサブセクションで検討する getBean()メソッドの5つの異なるシグネチャを提供します。

3.1. 名前によるBeanの取得

名前を使用してLionbeanインスタンスを取得する方法を見てみましょう。

Object lion = context.getBean("lion");

assertEquals(Lion.class, lion.getClass());

このバリアントでは、名前を指定し、その代わりに、指定された名前のBeanがアプリケーションコンテキストに存在する場合、Objectクラスのインスタンスを取得します。 それ以外の場合、Beanのルックアップが失敗すると、この実装と他のすべての実装の両方がNoSuchBeanDefinitionExceptionをスローします。

主な欠点は Beanを取得した後、目的のタイプにキャストする必要があります。 これにより、別の例外が発生する可能性があります返されたBeanのタイプが予想と異なる場合

取得しようとするとします名前を使用して “ライオン”。 結果をにキャストすると 、それは投げます ClassCastException

assertThrows(ClassCastException.class, () -> {
    Tiger tiger = (Tiger) context.getBean("lion");
});

3.2. 名前とタイプによるBeanの取得

ここでは、要求されたBeanの名前とタイプの両方を指定する必要があります。

Lion lion = context.getBean("lion", Lion.class);

前の方法と比較すると、タイプの不一致に関する情報を即座に取得できるため、この方法の方が安全です。

assertThrows(BeanNotOfRequiredTypeException.class, () -> 
    context.getBean("lion", Tiger.class));
}

3.3. タイプによるBeanの取得

getBean()、の3番目のバリアントでは、Beanタイプのみを指定するだけで十分です。

Lion lion = context.getBean(Lion.class);

この場合、潜在的にあいまいな結果に特別な注意を払う必要があります。

assertThrows(NoUniqueBeanDefinitionException.class, () -> 
    context.getBean(Animal.class));
}

上記の例では、LionTigerの両方がAnimalインターフェースを実装しているため、タイプを指定するだけでは結果を明確に判断するのに十分ではありません。 したがって、NoUniqueBeanDefinitionExceptionが発生します。

3.4. コンストラクターパラメータを使用した名前によるBeanの取得

Bean名に加えて、コンストラクターパラメーターを渡すこともできます。

Tiger tiger = (Tiger) context.getBean("tiger", "Siberian");

このメソッドは、プロトタイプスコープを持つBeanにのみ適用されるため、少し異なります。

シングルトンの場合、 BeanDefinitionStoreException。

プロトタイプbeanは、アプリケーションコンテナーから要求されるたびに新しく作成されたインスタンスを返すため、 get Bean()を呼び出すときに、コンストラクターパラメーターをオンザフライで提供できます。 ]:

Tiger tiger = (Tiger) context.getBean("tiger", "Siberian");
Tiger secondTiger = (Tiger) context.getBean("tiger", "Striped");

assertEquals("Siberian", tiger.getName());
assertEquals("Striped", secondTiger.getName());

ご覧のとおり、各 Tiger は、Beanを要求するときに2番目のパラメーターとして指定したものに応じて異なる名前を取得します。

3.5. コンストラクターパラメータを使用したタイプによるBeanの取得

このメソッドは最後のメソッドに似ていますが、最初の引数として名前の代わりにタイプを渡す必要があります。

Tiger tiger = context.getBean(Tiger.class, "Shere Khan");

assertEquals("Shere Khan", tiger.getName());

コンストラクターパラメータを使用して名前でBeanを取得するのと同様に、このメソッドはプロトタイプスコープのBeanにのみ適用されます。

4. 使用上の考慮事項

で定義されているにもかかわらず BeanFactory インターフェース、 getBean() メソッドは、 ApplicationContext。 通常、 プログラムでgetBean()メソッドを直接使用したくない

Beanはコンテナで管理する必要があります。 それらの1つを使用したい場合は、 依存性注入に直接電話するのではなく ApplicationContext.getBean() 。 そうすることで、アプリケーションロジックとフレームワーク関連の詳細が混在することを回避できます。

5. 結論

このクイックチュートリアルでは、 BeanFactoryインターフェイスからのgetBean()メソッドのすべての実装を確認し、それぞれの長所と短所について説明しました。

ここに示されているすべてのコード例は、GitHubから入手できます。