【问题标题】:Spring/DI: Constructor injection in child classSpring/DI:子类中的构造函数注入
【发布时间】:2017-03-29 06:39:03
【问题描述】:

我有一个带有构造函数注入依赖项的父类:

class ParentClass {
  private final MyService service;

  @Autowired
  ParentClass(MyService service) {
    this.service=service;
  }
  // ...
}

如果我从这个类继承,我是否总是需要重新定义一个调用父构造函数的构造函数?

class ChildClass extends ParentClass {
  // Do I really need this?
  @Autowired
  ChildClass(MyService service) {
    super(service);
  }
  // ...
}

使用 setter 注入,我似乎能够将依赖项保留在父类中,并且不需要在子类中重新连接它,如果子类不触及与依赖项相关的功能,这对我来说听起来不错:

class ParentClass {
  private MyService service;

  @Autowired
  void setMyService(MyService service) {
    this.service=service;
  }
  // ...
}

class ChildClass extends ParentClass {
  // ...
}

看来,如果我想避免重复自动装配代码并处理子项中的依赖关系,我只能使用 setter 或字段注入来做到这一点。

是否有更简洁的模式来执行这种依赖注入,或者这是必须使用字段/设置器注入的情况,即使建议使用构造函数注入?

谢谢!

【问题讨论】:

  • 在纯 java 中,如果你有一个带有非默认构造函数(无参数构造函数)的父类,在你的子类中你必须重新定义一个调用非默认父构造函数的构造函数。所以它与你关于构造函数的问题有关,Spring/DI 与它无关。
  • 谢谢。我的问题是关于 DI 问题。为了清楚起见,我对其进行了编辑。
  • 此刻你也在问“如果我从这个类继承,我是否总是需要重新定义一个调用父构造函数的构造函数?”。也许您应该编辑您的问题,因为目前答案是肯定的,您必须这样做,而且与 DI 无关
  • 更新了我的答案,请看一下

标签: java spring dependency-injection


【解决方案1】:

这不是 Spring 问题,而是 Java。尝试删除子类构造函数,看看你自己会发生什么——你的代码不应该编译。见this的回答,前面已经介绍过了。

回答您关于依赖注入的问题,是的,@Autowired 适用于父类中的 setter,但只要您不在子类中覆盖它(试一试)。原因是 Spring 处理的是对象,而不是类,所以当子类被实例化时,Spring 不会检查父类中重写方法的注释,除非注释被标记为 @Inherited@Autowired 不是)。

因此,您要么必须为每个子类使用 @Autowired(实际上我认为这不是一个大问题),要么切换到 setter 注入,用委托替换子类,或者使父类抽象并使用构造函数只在子类中注入。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多