【问题标题】:Spring constructor injection and super call verbositySpring构造函数注入和超级调用冗长
【发布时间】:2017-01-10 13:06:30
【问题描述】:

自从 Spring 宣布不推荐使用字段注入以来,我开始在我的项目中使用构造函数注入。实际上,代码感觉更漂亮,更严格,我可以接受。 但我遇到了一个看起来有点……奇怪和冗长的模式:

我有一个抽象服务 bean 类(带有 @Service 注释),它有 2 个依赖项,直接注入到构造函数中:

@Autowired
public AbstractService(DependencyA depA, DependencyB depB) {
    this.depA = depA;
    this.depB = depB;
}

然后我有多个服务 bean 类(仍然使用 @Serviceannotation)扩展抽象类。 而且我不知道是否有另一种方法,但这是我发现在每个子类构造函数中为父级注入依赖项的地方有点冗长和重复:

@Service
public class ServiceA extends AbstractService {
    private final DepC depC;

    @Autowired
    public ServiceA(DepA depA, DepB depB, DepC depC) {
        super(depA, depB);
        this.depC = depC;
    }

}

我只是想知道这是否正确,您对此有何看法?

【问题讨论】:

  • 为什么要冗长或重复。是的,对于只有一个可能的构造函数的类,你可以这样说,但是如果AbstractService 中有多个不同的重载构造函数怎么办,ServiceA 将如何确定调用哪个。但是是的,这是正确的方法。
  • @Autowired 上的 AbstractService 没有任何作用。
  • 我看不出你为什么需要用@Autowired注释你的抽象构造函数。这不是必需的,因为您的字段将被注入到您的超类构造函数中。其他一切看起来都很好。

标签: java spring dependency-injection


【解决方案1】:

AbstractService 上的 @Autowired 不执行任何操作。将其更改为:

@Service
public class ServiceA extends AbstractService {
    private final DepC depC;

    @Autowired
    public ServiceA(DepA depA, DepB depB, DepC depC) {
        super(depA, depB);
        this.depC = depC;
    }
}

...

public AbstractService(DependencyA depA, DependencyB depB) {
    this.depA = depA;
    this.depB = depB;
}

我对这个设置没问题。

对我来说,使用构造函数注入的主要好处是告知开发人员什么是外部依赖项。我发现它在编写单元测试时很有用。编写 mock 时,您只知道需要 mock 什么。

另一个好处是当一个类有太多依赖时突出显示,它提示重构可能是有序的。

替代方案将使用 setter 注入(同时保留信息方面),但我已经开始喜欢构造函数注入了。

【讨论】:

  • 好吧,我同意你的看法。 Setter 注入将是一个解决方案,但我更喜欢构造函数注入,因为字段可以是final。而且我从没想过从超类构造函数中删除@Autowired 注释,但现在我看到了你的代码。
【解决方案2】:

我的回答集中在您问题中的“冗长和重复”部分;我让其他人决定您对注释的使用有多“正确”。

即使有了 Spring 和它的 DI 框架,最后我们还是在谈论 Java 源代码!

而在 Java 中,如果您的基类提供了一个接受一些 A 和 B 的构造函数;那么当然你的子类必须调用 super(A a, B b);当然,这些值 a 和 b 必须来自某个地方!

因此,您所说的“冗长和重复”是使用 Java 的直接后果。

换句话说:没有办法避免那部分!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多