安装者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需要依赖关系。