关于依赖注入中setter注入和构造器注入的区别的思考

依赖注入Setter注入和构造器注入的区别
摘要由CSDN通过智能技术生成


Spring 依赖注入有两种方式:
构造器注入 (Constructor-based Dependency Injection)
Setter 注入(Setter-based Dependency Injection)
今天再看官方文档对于两者选择时意识到自己并不知道这两者的区别。将自己的学习记录一下。

官方文档解释

对于这两种注入方式的选择,官方文档给出的说明如下。

Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to use constructors for mandatory dependencies and setter methods or configuration methods for optional dependencies. Note that use of the @Required annotation on a setter method can be used to make the property be a required dependency; however, constructor injection with programmatic validation of arguments is preferable.

The Spring team generally advocates constructor injection, as it lets you implement application components as immutable objects and ensures that required dependencies are not null. Furthermore, constructor-injected components are always returned to the client (calling) code in a fully initialized state. As a side note, a large number of constructor arguments is a bad code smell, implying that the class likely has too many responsibilities and should be refactored to better address proper separation of concerns.

Setter injection should primarily only be used for optional dependencies that can be assigned reasonable default values within the class. Otherwise, not-null checks must be performed everywhere the code uses the dependency. One benefit of setter injection is that setter methods make objects of that class amenable to reconfiguration or re-injection later. Management through JMX MBeans is therefore a compelling use case for setter injection.

Use the DI style that makes the most sense for a particular class. Sometimes, when dealing with third-party classes for which you do not have the source, the choice is made for you. For example, if a third-party class does not expose any setter methods, then constructor injection may be the only available form of DI.

翻译一下后大致的主要观点如下:

  1. 一般的经验为:构造函数用于强制依赖项,而将 setter 方法或配置方法用于可选依赖项(注意:在 setter 方法上使用 @Required 注释可用于使属性成为必需的依赖项)
  2. 构造函数好处是允许您将应用程序组件实现为不可变对象,并确保所需的依赖项不为空。
  3. 大量的构造函数参数是一种难闻的代码气味,这意味着该类可能有太多的职责,应该重构以更好地解决关注点的正确分离。
  4. setter 注入的一个好处是,setter 方法使该类的对象适合于以后的重新配置或重新注入

好吧,看完后云里雾里。

大佬解释

看了一下其他大佬的博客对这个问题的解释。
文章链接:Spring set注入和构造注入的区别

大意如下:
对于Setter注入:因为Spring调用一个对象的set方法注入前,这个对象必须先被实例化。所以在"使用set方法注入"的情况下Spring会首先调用对象的构造函数。
对于构造器注入:如果发现配置了对象的构造注入,那么Spring会在调用构造函数前把构造函数需要的依赖对象都实例化好,然后再把这些实例化后的对象作为参数去调用构造函数。
主要区别为

  • 在使用构造函数和set方法依赖注入时,Spring处理对象和对象依赖的对象的顺序时不一样的
  • 通过构造函数的注入方式其实表达了2个对象间的一种强的依赖关系:组合关系
  • 通过set方法注入的方式表达了2个对象间较弱的依赖关系:聚合关系

代码演示

用简单的代码演示一下不同的注入方式对于实例化顺序的影响
大致思路为 User 类中需要传入一个 Name类的实例,分别用Set方法和构造器传入。

构造器注入

User 类

public class User 
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值