当前位置: 首页 > 知识库问答 >
问题:

解释为什么构造函数注入优于其他选项[重复]

谢运良
2023-03-14

在一本支持Spring3的书中,第4章——Spring中的IOC和DI简介——第59页,在“Setter注入与构造函数注入”一节中,有一段说

包括Spring,提供了一种机制,用于确保在使用Setter注入时定义所有依赖项,但通过使用构造函数注入,您可以以与容器无关的方式断言对依赖项的需求。”

你能举例解释一下吗

共有3个答案

益智明
2023-03-14

为了简单起见,让我们假设我们可以对强制依赖使用基于构造函数的依赖注入,对可选依赖使用基于setter的注入。这是一条经验法则!!

比如说。

如果你想实例化一个类,你总是用它的构造函数。因此,如果您使用基于构造函数的注入,实例化类的唯一方法是通过该构造函数。如果您通过构造函数传递依赖项,很明显它是一个强制性依赖项。

另一方面,如果POJO类中有setter方法,则可以使用该setter方法为类变量设置值,也可以不使用该方法。这完全是基于你的需要。i、 它是可选的。因此,如果通过类的setter方法传递依赖项,则隐式表示它是可选依赖项。希望这是清楚的!!

焦同
2023-03-14

(…)通过使用构造函数注入,您可以以容器无关的方式断言依赖项的需求

这意味着您可以强制执行所有注入字段的要求,而无需使用任何特定于容器的解决方案。

随着setter注入特殊Spring注释@必需是必需的。

@必需的

将方法(通常是JavaBean setter方法)标记为“必需”:也就是说,setter方法必须配置为用值注入依赖关系。

用法

import org.springframework.beans.factory.annotation.Required;

import javax.inject.Inject;
import javax.inject.Named;

@Named
public class Foo {

    private Bar bar;

    @Inject
    @Required
    public void setBar(Bar bar) {
        this.bar = bar;
    }
}

所有必填字段都在构造函数(纯Java解决方案)中定义。

用法

import javax.inject.Inject;
import javax.inject.Named;

@Named
public class Foo {

    private Bar bar;

    @Inject
    public Foo(Bar bar) {
        this.bar = bar;
    }

}

这在单元测试中特别有用。这样的测试应该非常简单,并且不理解像@必需这样的注释,它们通常不需要Spring来运行简单的单元测试。当使用构造函数时,这个类的测试设置要容易得多,不需要分析被测试类是如何实现的。

淳于坚壁
2023-03-14

将必需的依赖项作为构造函数参数的类只能在提供该参数的情况下实例化(您应该有一个保护子句来确保该参数不为空)(或者在静态编程语言中使用不可为空的类型)。因此,无论您是否使用Spring,构造函数都会强制执行依赖项要求,使其与容器无关。

如果使用setter注入,则setter可能会被调用,也可能不会被调用,因此实例可能永远不会提供其依赖项。强制调用setter的唯一方法是使用@Required@Autowired,这是特定于Spring的,因此不区分容器。

因此,为了使代码独立于Spring,请使用构造函数参数进行注入。这适用于测试;在普通单元测试中实例化和测试类会更容易,而不需要配置应用程序上下文或设置集成测试所带来的复杂性。

更新:Spring4.3将在单个构造函数场景中执行隐式注入,通过根本不需要@Autowired注释,使您的代码更加独立于Spring。

 类似资料:
  • 问题内容: 在Pro Spring 3丛书的第4章-Spring中的IOC和DI简介-第59页中的“ Setter注入与构造方法注入”部分中,一段说 包括Spring,提供了一种机制来确保在使用Setter Injection时定义了所有依赖关系,但是通过使用Constructor Injection,你可以以与容器无关的方式声明对依赖关系的要求。” 你能举例说明一下吗 问题答案: 将必需的依赖项

  • 问题内容: 在Jackson中,当您使用注释构造函数时,必须使用注释其参数。所以这个构造函数 变成这个: 我不明白为什么有必要。你能解释一下吗? 问题答案: Jackson必须知道以什么顺序将字段从JSON对象传递给构造函数。使用反射无法在Java中访问参数名称-这就是为什么您必须在注释中重复此信息的原因。

  • 本文向大家介绍请解释Java中的概念,什么是构造函数?什么是构造函数重载?什么是复制构造函数?相关面试题,主要包含被问及请解释Java中的概念,什么是构造函数?什么是构造函数重载?什么是复制构造函数?时的应答技巧和注意事项,需要的朋友参考一下 考察点:JAVA构造函数 当新对象被创建的时候,构造函数会被调用。每一个类都有构造函数。在程序员没有给类提供构造函数的情况下,Java编译器会为这个类创建一

  • 问题内容: 在Jackson中,当用注释构造函数时,必须用注释其参数。所以这个构造函数 变成这个: 我不明白为什么有必要。你能解释一下吗? 问题答案: Jackson必须知道以什么顺序将字段从JSON对象传递给构造函数。使用反射无法在Java中访问参数名称-这就是为什么您必须在注释中重复此信息的原因。

  • 问题内容: 在Java的构造函数中,如果要调用另一个构造函数(或超级构造函数),则它必须是该构造函数的第一行。我认为这是因为不允许您在其他构造函数运行之前修改任何实例变量。但是,为什么不能在构造函数委派之前使用语句,以便计算另一个函数的复杂值?我想不出任何正当的理由,在一些实际案例中,我编写了一些丑陋的代码来解决此限制。 所以我只是想知道: 有此限制的充分理由吗? 有没有计划在将来的Java版本中

  • 有人能帮助实现没有注释的Guice吗? pom。xml 我所尝试的: 我得到的错误是: 我理解这个错误。 但是我希望我可以“指向”Guice到正确的构造函数......而不是使用注释。 如您所见,使用默认/空构造函数不是一个好选择,因为这个示例很简单,但我想坚持使用基于构造函数的注入。 附加: 根据我在评论中从赫曼特·辛格那里得到的“暗示”,我想我离得更近了。 我创建了一个ProductionIn