知識庫 / Spring RSS 訂閱

Spring 通用類型自動裝配

Spring
HongKong
5
01:42 PM · Dec 06 ,2025

1. 概述

在本教程中,我們將學習如何通過泛型參數注入 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 類型實例 Bean 到這個列表中。無論我們如何通過 Java 或 XML 配置來實例化這些 Bean,都不會影響。

我們還可以使用限定符來獲取 Vehicle 類型中特定的 Bean。然後我們創建 @CarQualifier 並用 @Qualifier 標註它:

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

現在我們可以使用此標註來從我們的列表中獲取特定的 車輛

@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 中自動裝配泛型。

假設我們還有一個名為 MotorcycleVehicle 子類:

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

現在,如果我們想要只將 Car 類型的豆子注入到我們的列表中,而不注入任何 Motorcycle 類型的豆子,我們可以通過使用特定的子類作為類型參數來實現:

@Autowired
private List<Car> vehicles;

Spring 允許我們使用泛型類型作為限定符,無需在版本 4.0 之後進行顯式註解。

在 Spring 4.0 之前,上述代碼無法與 Vehicle 類及其子類的多個子類中的 Bean 一起使用。 缺少顯式限定符,我們會收到 NonUniqueBeanDefinitionException

4. 可解析類型 (ResolvableType)

泛型自動裝入功能借助可解析類型類在幕後工作。

它在 Spring 4.0 中引入,用於封裝 Java 類型並處理對超類型、接口、泛型參數以及最終解析為類的訪問。

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. 結論

類型注入是一種強大的特性,它省去了開發者手動指定限定符的精力,使代碼更簡潔、更易於理解。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.