You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

依赖注入场景下,如何让中间类获取注入对象传递给父类构造器?

解决ElectricVehicle构造器获取ElectricEngine的可行方案

方案1:显式注入ElectricEngine到ElectricVehicle构造器,利用DI框架自动传递

让ElectricVehicle的构造器依赖注入ElectricEngine,子类Tesla仅需传递转向系统参数,DI框架会自动为父类提供ElectricEngine的单例实例。

class ElectricVehicle extends Vehicle {
  // 注入Singleton的ElectricEngine,DI框架自动处理实例获取
  @Inject
  ElectricVehicle(ElectricEngine engine, SteeringSystem ss) {
    super(engine, ss);
  }
}

class Tesla extends ElectricVehicle {
  @Inject
  Tesla(ElectricEngine engine, SteerByWireSystem ss) {
    super(engine, ss);
  }
}

虽然Tesla构造器仍需声明ElectricEngine参数,但这是Java构造器调用规则的要求——子类必须显式传递父类构造器所需参数。实际使用中,DI框架会自动注入ElectricEngine的单例实例,你无需手动创建或传递,Tesla代码也无需关心ElectricEngine的具体实现细节。

方案2:使用静态工厂类封装ElectricEngine的获取

创建单例工厂类,由DI框架注入ElectricEngine实例,ElectricVehicle通过工厂获取实例并传递给父类。

// 工厂类,由DI注入初始化实例
class EngineFactory {
  private static ElectricEngine electricEngineInstance;

  @Inject
  EngineFactory(ElectricEngine engine) {
    electricEngineInstance = engine;
  }

  public static ElectricEngine getElectricEngine() {
    return electricEngineInstance;
  }
}

class ElectricVehicle extends Vehicle {
  ElectricVehicle(SteeringSystem ss) {
    super(EngineFactory.getElectricEngine(), ss);
  }
}

class Tesla extends ElectricVehicle {
  @Inject
  Tesla(SteerByWireSystem ss) {
    super(ss);
  }
}

这种方式让Tesla完全无需关心Engine相关参数,ElectricVehicle通过工厂获取预初始化的ElectricEngine单例。需注意必须确保EngineFactory在ElectricVehicle实例化前被DI框架初始化,避免空指针异常。

方案3:利用DI框架的辅助注入(如Dagger的@AssistedInject)

如果使用Dagger这类支持辅助注入的框架,可通过@AssistedInject分离手动传递的参数(如转向系统)和DI自动注入的参数(如Engine)。

class ElectricVehicle extends Vehicle {
  @AssistedInject
  ElectricVehicle(ElectricEngine engine, @Assisted SteeringSystem ss) {
    super(engine, ss);
  }

  // 定义辅助工厂接口,用于创建实例
  @AssistedFactory
  interface Factory {
    ElectricVehicle create(SteeringSystem ss);
  }
}

class Tesla extends ElectricVehicle {
  @AssistedInject
  Tesla(ElectricEngine engine, @Assisted SteerByWireSystem ss) {
    super(engine, ss);
  }

  @AssistedFactory
  interface Factory {
    Tesla create(SteerByWireSystem ss);
  }
}

使用时只需注入Tesla.Factory,调用create(steerByWireSystem)即可创建Tesla实例——ElectricEngine由DI框架自动注入,无需在Tesla代码中显式声明或传递,完美满足“底层子类无需指定Engine类型”的需求。

方案4:抽象类+构造器约束

将ElectricVehicle设为抽象类,强制子类通过DI注入ElectricEngine,同时通过构造器封装隐藏细节:

abstract class ElectricVehicle extends Vehicle {
  protected ElectricVehicle(ElectricEngine engine, SteeringSystem ss) {
    super(engine, ss);
  }
}

class Tesla extends ElectricVehicle {
  @Inject
  Tesla(ElectricEngine engine, SteerByWireSystem ss) {
    super(engine, ss);
  }
}

这种方式通过抽象类明确ElectricVehicle家族必须使用ElectricEngine,Tesla构造器虽仍需声明ElectricEngine参数,但DI框架会自动处理注入,且Tesla无需关心Engine的具体实现逻辑。

内容的提问来源于stack exchange,提问作者kane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 15:13:18