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

如何正确执行依赖注入(在Spring中)?[重复]

路奇
2023-03-14

我对使用Spring向类注入对象有疑问。我在我的项目中使用了这样的代码:

@Resource // or @Autowired even @Inject
private PersonRepository personRepository;

然后通常在以下方法中使用:

personRepository.save(p);

否则,我在Spring示例中发现,注入构造函数:

private final PersonRepository personRepository;

@Autowired
public PersonController(PersonRepository personRepository) {
  this.personRepository = personRepository;
}

所以这两个都是正确的?或者每一个都有它的属性和用法?

共有2个答案

段曦
2023-03-14

从学术上讲,我同意构造函数只是创建对象的更好方法。然而,java bean规范是建立在诱变器的前提上的,以便于反思。围绕这一便利访问范式建立了太多的工具和框架。对于服务、DAO和其他单例场景,我认为只有构造函数注入应该被用作变异器,打破了“只有朋友才能看到你的私密部分”的古老规则。

昝唯
2023-03-14

后者是正确的,这与其说是因为Spring或任何依赖注入容器,不如说是因为面向对象的类设计原则。

应设计类型,以便只能从中创建处于有效状态的实例。为了实现这一点,该类型的所有强制依赖项都需要是构造函数参数。这意味着,可以对这些依赖项进行null-检查,并将其分配给最终字段,以促进不变性。除此之外,在使用代码时,对于该实例的调用方(或创建者),它必须提供哪些依赖项(通过浏览API文档或在IDE中使用代码完成)是显而易见的。

所有这些在场注入中是不可能的。您没有从外部看到依赖关系,您需要一些黑魔法来注入依赖关系,并且您永远无法确定它们是否为空,除非您盲目地信任容器。

最后但并非最不重要的方面实际上是,通过字段注入,向类添加大量依赖项会减少痛苦,这本身就是一个设计问题。构造函数在更早的时候变得更加痛苦,这是一件好事,因为它告诉你一些关于你的类设计的事情:类有太多的责任。首先不需要计算它的指标,当你试图扩展它时,你会感觉到它。

人们经常认为这只是学术上的胡说八道,因为你无论如何都可以依赖容器。以下是我的看法:

>

即使是为容器使用而设计的类型,也将手动使用:在单元测试中。如果你不写单元测试...那就是另一个话题了。

额外构造函数的所谓冗长(“我可以用一行场注入实现同样的事情!!”-“不,你不能。你实际上从多写一行代码中得到了东西。”)可以通过像龙目岛这样的东西来缓解。使用Spring和Lombok注入组件的构造函数如下所示:

@Component
@RequiredArgsConstructor
class MyComponent implements MyComponentInterface {

  private final @NonNull MyDependency dependency;

  …
}

Lombok将负责为每个最终字段生成一个构造函数,并在赋值之前检查给定参数的null。因此,您可以有效地获得字段注入的简洁性和构造函数注入的设计优势。

我最近参加了与一些非Java人的讨论,他们对构造函数DI使用术语“注入”感到非常困惑。实际上,他们认为——这有很多事实——通过构造函数传递依赖根本不是注入,因为这是将对象传递给其他对象的最自然的方式(与任何类型的注入形成鲜明对比)。

也许我们应该为这种风格创造一个不同的术语?也许是依赖喂养?

  • 奥利弗·吉尔克-为什么田野注射是邪恶的
  • Jens Schauder-一个正确的方法来做依赖注入
 类似资料:
  • 问题内容: 我对使用Spring将对象注入到类中有疑问。我在项目中使用了以下代码: 然后通常在以下方法上使用它: 否则,我在Spring示例中发现了注入构造函数的情况: 所以两者都正确吗?还是每个都有其属性和用法? 问题答案: tl; dr-构造函数注入是执行DI的最佳方法 后者是正确的,并不是因为Spring或任何依赖注入容器,而是面向对象的类设计原则。 细节 应该设计一种类型,以便您只能根据其

  • 我已经使用GoogleGuice几个月了。我对它很满意,但似乎我用错了。我创造了很多辅助注射,有时还有两个注射器。 因此,我想了解这里的一般原则。 是否应该为连接主类所有内容的所有应用程序配备一个喷油器? 最佳实践是关于从应用程序一开始就尝试在构造函数中注入大量内容吗?(我看到了测试的优势) 我的主要问题是,有时我觉得某些对象组的创建属于某个组件。有必要封装它吗?你会如何处理? 当您拥有一个重要的

  • 我尝试用Spring-Boot创建一个spring web应用程序。我的第一个问题是依赖注入对我不起作用。这是我跟踪的那篇文章。 我创建了一个应用程序类: 我的分级文件: 我所期望的:当我打开/greeting页面时,将出现log,但我在的开头得到了这一点: 2017-09-12 10:47:56.058警告7545--[main]ConfigEmbeddedWebApplicationConte

  • 我试图了解spring依赖注入是如何工作的。根据我的理解,如果我们将一个类声明为带有注释的bean,并在需要注入依赖关系的另一个类中为该bean使用注释,则会将该bean注入为依赖关系。对于例如。 假设我们有接口,实现,并且我们将声明为。如果我们有一个带有引用的主类,并且我们在Iservice引用上做了注释,则将被注入到引用中。 但是,我的问题是,如果有两个类和实现,并且我们使用。spring将如

  • 我遇到了依赖注入周期问题。我请求重新设计建议。提前谢谢。 错误描述:应用程序上下文中某些bean的依赖关系形成一个循环: 这是两个班 第一类: 第二类:

  • 我似乎无法导入任何添加的依赖项。在下面的代码(pom.xml)中,我们看到了可以工作的JavaFX依赖项,以及我自己添加但不工作的MongoDB依赖项。 工作的JavaFX语句: 这些不起作用。 当给出错误时:包'org.bson'在模块'org.mongodb.bson'中声明,但是模块'com.jonathan.woollettlight'没有读取它。并且给出 我的文件结构: 扩展了Mongo