現場注入

上述相同的例子也可以使用所謂的場注入來完成。我們不是用 @Inject 註釋建構函式,而是註釋我們希望注入的欄位

public class Spaceship {

    @Inject
    private PropulsionSystem propulsionSystem;
    @Inject
    private NavigationSystem navigationSystem;

    public void launch() throws FlightUnavailableException {
        if (propulsionSystem.hasFuel()) {
            propulsionSystem.engageThrust();
        } else {
            throw new FlightUnavailableException("Launch requirements not met. Ship needs fuel.");
        }
    }

}

請注意,欄位注入不需要 getter / setter 方法。另請注意,該欄位不需要是公開的,實際上可以是私有的,但它不能是最終的。但是,將欄位設為私有將使編寫程式碼的測試更加困難,因為如果沒有 setter,測試將不得不使用反射來修改欄位。

另請注意,如果需要,可以串聯使用建構函式注入和欄位注入,但應根據具體情況仔細評估是否有意義。也許在使用遺留程式碼時,必須在不修改建構函式簽名的情況下向類新增依賴項,這是出於某些特殊原因。

public class Spaceship {

    private PropulsionSystem propulsionSystem;
    @Inject
    private NavigationSystem navigationSystem;

    @Inject
    public Spaceship(PropulsionSystem propulsionSystem) {
        this.propulsionSystem = propulsionSystem;
    }

    public void launch() throws FlightUnavailableException {
        if (propulsionSystem.hasFuel()) {
            propulsionSystem.engageThrust();
        } else {
            throw new FlightUnavailableException("Launch requirements not met. Ship needs fuel.");
        }
    }

}