olNGIb4NkK5r2x7x4oG3GpEzizVpnY6KNCck9cym

開發 Spring/Spring Boot 應用程式時,如果一個類別中有多個建構函數(constructor)時,需要顯式使用 @Autowired 註解

開發 Spring/Spring Boot 應用程式時,如果一個類別中有多個建構函數(constructor)時,需要顯式使用 @Autowired 註解

在 Spring Framekwork 中,提供了 @Autowired 註解(annotation)用以標記需要自動注入 Spring IoC Container 的物件,亦即其作用是 讓 Spring 得以自動尋找並提供所需的物件,而不需要交由開發者手動建立與管理,或者更白話一點地說:省去手動使用 new 來將物件實例化,讓 Spring 負責依賴關係的管理

雖然說 @Autowired 支持了多種依賴注入的方式,比如使用屬性注入、使用 setter 方法注入以及使用建構函數(constructor)注入,但其中仍以使用建構函數(constructor)注入最為常見。由於這樣的情境十分常見,在 Spring 4.3 版本之後,如果類別中只有一個建構函數,那麼 Spring 會自動進行依賴注入,不需要再加上 @Autowired 註解。

這樣的方式大幅地減少了需要手動加上 @Autowired 的情況,但同時也是新手容易犯的錯誤,尤其是當類別中有一個以上的建構函數(constructor)時:

@Component
public class MyService {

    private final DependencyA dependencyA;
    private final DependencyB dependencyB;

    // 多個 constructor,需要使用 @Autowired
    @Autowired
    public MyService() {
        this.dependencyA = new DependencyA(); // 預設值或其他方式初始化
    }

    public MyService(DependencyA dependencyA, DependencyB dependencyB) {
        this.dependencyA = dependencyA;
        this.dependencyB = dependencyB;
    }
}

在上述範例中,如果沒有顯式的 @Autowired 註解,並且存在無參數的建構函數,預設將會採用該建構函數進行注入;若是沒有顯式的 @Autowired 註解,並且沒有存在無參數的建構函數,則在程式運行時 Spring 會無法確定應該使用哪個建構函數從而拋出錯誤。因此建議做法如下:

  • 最佳實踐是僅使用單一的 constructor 避免混營,並且不需要顯式的 @Autowired 註解。
  • 倘若需要有多個 constructor 存在,則務必要使用顯式的 @Autowired 註解,明確指定 Spring 應該使用哪個。

張貼留言