现场注入

上述相同的例子也可以使用所谓的场注入来完成。我们不是用 @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.");
        }
    }

}