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

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

1. 概要

このチュートリアルでは、Spring Beanをgeneric parametersで注入する方法を説明します。

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 vehicles;

Spring will autowire all the Vehicle instance beans into this list.JavaまたはXML構成を介してこれらのBeanをどのようにインスタンス化するかは重要ではありません。

修飾子を使用して、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 vehicles;

この場合、複数のVehicle Beanを作成できますが、Springは@CarQualifierを持つBeanのみを上記のリストに挿入します。

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

3. Spring 4.0でのジェネリックの自動配線。

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

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

ここで、Car Beanのみをリストに挿入し、Motorcycle onesは挿入しない場合は、特定のサブクラスを型パラメーターとして使用することでこれを行うことができます。

@Autowired
private List vehicles;

バージョン4.0以降、明示的な注釈を必要としないSpring lets us use a generic type as a qualifier

Spring 4.0より前は、上記のコードはVehicle.の複数のサブクラスのBeanでは機能しませんでした。明示的な修飾子がないと、NonUniqueBeanDefinitionExceptionを受け取ります。

4. ResolvableType

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

Java Typeをカプセル化し、スーパータイプ、インターフェース、汎用パラメーターへのアクセスを処理し、最終的にクラスに解決するために、Spring 4.0で導入されました。

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
class com.example.model.Vehicle

5. 結論

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

いつものように、コードはover on GitHubで見つけることができます。