ジェネリック型の春の自動配線

1.概要

このチュートリアルでは、https://www.baeldung.com/java-generics[一般的なパラメータ]を使用して、Spring Beanを注入する方法を説明します。

2. Spring 3.2における自動配線ジェネリックス.

Springはバージョン3.2以降のジェネリック型のインジェクションをサポートしています。

__Vehicle という抽象クラスとその Carという具象サブクラスがあるとします。

public abstract class Vehicle {
    private String name;
    private String manufacturer;

   //... getters, setters etc
}
public class Car extends Vehicle {
    private String engineType;

   //... getters, setters etc
}

Vehicle 型のオブジェクトのリストを何らかのハンドラクラスに注入したいとします。

@Autowired
private List<Vehicle> vehicles;
  • Springはすべての Vehicle インスタンスBeansをこのリストに自動配線します。** これらのBeansをJavaまたはXML設定でどのようにインスタンス化するかは重要ではありません。

Vehicle 型の特定のBeanだけを取得するために修飾子を使うこともできます。それから @ CarQualifier を作成し、それに @ Qualifier というアノテーションを付けます。

@Target({
  ElementType.FIELD,
  ElementType.METHOD,
  ElementType.TYPE,
  ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface CarQualifier {
}

これで、このアノテーションをリスト上で使用して、特定の Vehicles だけを取得することができます。

@Autowired
@CarQualifier
private List<Vehicle> vehicles;
  • この場合、いくつかの Vehicle Beanを作成することができますが、Springは @ CarQualifier を持つBeanのみを上記のリストに挿入します。**

public class CustomConfiguration {
    @Bean
    @CarQualifier
    public Car getMercedes() {
        return new Car("E280", "Mercedes", "Diesel");
    }
}

3. Spring 4.0におけるGenericsの自動配線.

Motorcycle という別の Vehicle サブクラスがあるとします。

public class Motorcycle extends Vehicle {
    private boolean twoWheeler;
   //... getters, setters etc
}

さて、リストに Car Beanだけをインジェクトし、 __ Motorcycle __onesをインジェクトしたくない場合は、特定のサブクラスを型パラメータとして使用してこれを実行できます。

@Autowired
private List<Car> vehicles;
  • Springでは、バージョン4.0以降、明示的なアノテーションを必要とせずに、** 総称型を修飾子として使用できます。

Spring 4.0より前のバージョンでは、上記のコードは__Vehicleの複数のサブクラスのBeanに対しては機能しませんでした。

4. ResolvableType

  • ジェネリックス自動配線機能は、舞台裏の ResolvableType クラスの助けを借りて機能します。**

これはSpring 4.0で導入され、Java Typeをカプセル化し、スーパータイプ、インターフェース、一般的なパラメータへのアクセスを処理し、最後にClassに解決します。

ResolvableType vehiclesType = ResolvableType.forField(getClass().getDeclaredField("vehicles"));
System.out.println(vehiclesType);

ResolvableType type = vehiclesType.getGeneric();
System.out.println(type);

Class<?> aClass = type.resolve();
System.out.println(aClass);

上記のコードの出力は、対応する単純型と総称型を示しています。

java.util.List<com.example.model.Vehicle>
com.example.model.Vehicle
class com.example.model.Vehicle

5.まとめ

ジェネリック型のインジェクションは強力な機能であり、開発者は明示的な修飾子を割り当てる手間を省くことができ、コードをよりクリーンで理解しやすくします。

いつものように、コードはhttps://github.com/eugenp/tutorials/tree/master/spring-core[over on GitHub]にあります。