为什么Spring推荐使用构造器注入?

在说注入时,我们先来回忆一下在Spring中依赖注入的方式

1.setter注入

2.构造器注入

3.基于注解的注入

 

1.setter注入

 

优点:

  1. 灵活性:可以动态地更改依赖对象,而不需要修改类的构造函数。
  2. 可读性:可以清晰地看到类的依赖关系,便于理解和维护。
  3. 测试性:便于进行单元测试,可以通过setter方法注入mock对象。

缺点:

  1. 代码量增加:需要为每个依赖对象编写一个setter方法,增加了代码量。
  2. 对象状态不确定:依赖对象可以在任何时候被更改,可能导致对象状态不确定性。

2.构造器注入

 

优点:

  1. 依赖注入更加明确和直观,可以清晰地看到一个类依赖了哪些其他类。
  2. 可以更容易地进行单元测试,因为可以轻松地用模拟对象替代真实的依赖对象。
  3. 依赖关系更加松散,可以更灵活地替换依赖对象。

缺点:

  1. 如果依赖对象很多,构造函数参数会变得很长,不够简洁。
  2. 如果依赖对象发生变化,需要修改构造函数的参数列表,可能会导致代码的修改量较大。

3.注解注入

 

优点

  1. 代码简洁:通过注解注入,可以减少大量的样板代码,使代码更加简洁易读。
  2. 松耦合:通过注解注入,可以将依赖关系从代码中抽离出来,实现了松耦合,方便进行单元测试和模块替换。
  3. 可维护性:通过注解注入,可以更方便地进行代码维护和重构,减少了代码的耦合度。

缺点:

  1. 难以定位问题:由于依赖关系是通过注解注入的方式实现的,当出现问题时,可能会比较难以定位问题的根源。
  2. 学习成本高:对于初学者来说,理解和使用注解注入可能需要一定的学习成本。
  3. 运行时性能开销:注解注入通常是在运行时进行的,可能会带来一定的性能开销。

现在我们回到问题,为什么Spring推荐使用构造器注入?

Spring官网的一段话

The Spring team generally advocates constructor injection as it enables one to implement application components as immutable objects and to ensure that required dependencies are not null. Furthermore constructor-injected components are always returned to client (calling) code in a fully initialized state.

看不懂?没关系,我给你翻译一下(你也可以自己翻译一下)

这个构造器注入的方式啊,能够保证注入的组件不可变,并且确保需要的依赖不为空。此外,构造器注入的依赖总是能够在返回客户端(组件)代码的时候保证完全初始化的状态

理清一下思路,做个总结

 

  • 依赖不可变:其实说的就是final关键字。
  • 依赖不为空(省去了我们对其检查):当要实例化Controller的时候,由于自己实现了有参数的构造函数,所以不会调用默认构造函数,那么就需要Spring容器传入所需要的参数,所以就两种情况:1、有该类型的参数->传入。2:无该类型的参数->报错。所以保证不会为空,Spring总不至于传一个null进去吧 😦
  • 完全初始化的状态:这个可以跟上面的依赖不为空结合起来,向构造器传参之前,要确保注入的内容不为空,那么肯定要调用依赖组件的构造方法完成实例化。而在Java类加载实例化的过程中,构造方法是最后一步(之前如果有父类先初始化父类,然后自己的成员变量,最后才是构造方法,这里不详细展开。)。所以返回来的都是初始化之后的状态。

简单来说有以下几个原因

  一、增强对象的不可变性

  二、保证依赖关系的完整性

  三、简化配置

  四、提供更好的测试支持

  五、避免循环依赖

  六、减少意外覆盖依赖


当然,如果你嫌构造器注入当一个类的参数太多,可能会使代码特别臃肿,你也可以使用注解注入的方式,在工作中因人而异,感谢阅读

 

posted @ 2023-12-12 13:48  杰Sir"1_v"  阅读(748)  评论(0)    收藏  举报