安装者DI与构造函数DI在spring?

Spring有两种types的DI:setter DI和construction DI。

基于构造器的DI修复了需要注入依赖关系的顺序。 基于设置器的DI不提供这个。

基于Setter的DI只有在需要时才帮助我们注入依赖关系,而不是在build造时要求它。

我没有看到任何其他的显着差异,因为这两种types的Spring DI提供了相同的function – 当代码启动时,setter和构造函数DI注入依赖关系。 当然,构造函数DI将通过构造函数完成,而构造函数DI将在构造该对象之后通过setter来完成,但对于开发人员在性能等方面没有任何区别。两者都提供了指定顺序的方法dependency injection也是如此。

我正在寻找一个场景,其中一个提供明显的优势,或者一个types完全无法使用。

说到spring的具体利弊:

  • 构造函数注入(来自定义)不允许你在bean之间创build循环依赖。 这个限制实际上是构造器注入的一个优点 – 当使用setter注入时,Spring可以解决循环依赖问题,甚至不用注意。

  • 另一方面,如果您使用构造函数注入CGLIB不能够创build代理,迫使您使用基于接口的代理或虚拟无参数构造函数。 参见: SPR-3150

你应该根据devise考虑来决定,而不是工具(Spring)的考虑。 不幸的是,Spring已经训练了我们使用setter注入,因为当它最初被构思时,在Java中没有“注释”这样的东西,在XML中,setter注入工作并且看起来好多了。 今天,我们从这些限制中解放出来,从而再次成为devise决策。 你的bean应该使用构造器注入来实现bean和setter注入所需的任何依赖关系,这些依赖关系是可选的,并且有一个合理的默认值,或多或less地像OOD从一开始就告诉我们的那样。

构造器注入:我们通过构造器注入依赖关系。

一般来说,我们可以使用强制性的依赖关系。

如果您使用构造函数注入,则有一个称为“循环依赖”的缺点

循环依赖:假设A和B.A依赖于B.B依赖于A.在这个构造器中注入将失败。 那时Setter注入是有用的。

如果对象状态不一致,则不会创build对象。

Setter注入:我们通过Setter方法注入依赖关系。

这对非强制性依赖关系很有用

可以使用Setter注入重新注入依赖关系构造器注入中不可能的

更喜欢setter注射。

想想没有spring会怎么样(正如Ryan所说的)。 你会传递构造函数的依赖? 如果依赖太多,这似乎是错误的。 另一方面,可以使用构造函数来强制执行对象的有效状态 – 要求所有依赖关系,并validation它们是否为非null。

代理是另一回事(正如Tomasz指出的那样) – 你将需要一个虚构的构造函数来破坏整个想法。

有一个第三个选项btw – 现场注入。 我倾向于使用,虽然这不是一个好devise决定,因为它节省了一个额外的setter,但如果这是spring以外使用,我将不得不添加setter。

不,即使构造函数注入发生,注入仍然工作,但只是有限的初始化,setter注入是可选的和灵活的。 但它通常可能是参数类,一个春豆与其他春豆

既然你可以混合使用,
构造器DI基于Setter的DI
对于可选的依赖关系,使用强制依赖和构造函数的构造函数参数是一个很好的经验法则。

请注意 ,在setter上使用@Required注释可以用来使setter需要依赖关系。