【Spring】为什么不建议使用@Autowired

开篇词:

最近提交PR后,有同事添加了comments:建议@autowired替换为构造器注入,正好借此来聊一下这个司空见惯的注解
在这里插入图片描述

干货篇:

1.知识回顾

@Autowired 是 Spring 框架中的一个注解,用于实现依赖注入(Dependency Injection, DI)。在 Spring 应用程序中,

@Autowired 可以自动地将一个 bean 注入到另一个 bean 中,前提是 Spring 容器中存在该类型的 bean。这使得 Spring 应用程序的组件之间的耦合度降低,提高了代码的可测试性和可维护性。

2.@Autowired和其他注入方式的对比

1.@Autowired 注入(字段注入)

优点:

  • 简单易用:只需在字段上添加 @Autowired 注解,Spring 容器会自动注入匹配的 bean,减少了代码量。
  • 灵活性高:可以在类的任何字段上使用,不受限制。

缺点:

  • 依赖关系不明确:其他开发者难以一眼看出类的依赖关系,增加了理解和维护的难度。
  • 难以测试:由于依赖是自动注入的,测试时难以替换或模拟依赖对象。
2.构造器注入

优点:

  • 明确依赖关系:通过构造器参数明确指定了类的依赖关系,提高了代码的可读性和可维护性。
  • 支持不可变对象:可以注入 final 修饰的字段,确保对象在创建后不会被修改。
  • 避免循环依赖:Spring 容器能够自动检测并处理构造器注入中的循环依赖问题。
  • 有利于单元测试:可以通过构造器注入模拟或替换依赖对象,便于编写单元测试。

缺点:

  • 灵活性较低:对类的依赖关系有严格的顺序要求,可能导致代码不够灵活。
  • 启动时间稍长:由于需要处理依赖关系的顺序和循环依赖问题,可能会稍微增加应用的启动时间。
3.Setter 方法注入

优点:

  • 灵活性高:可以在对象创建后通过 Setter 方法注入依赖,支持依赖的延迟加载。
  • 支持可选依赖:如果依赖不是必需的,可以在 Setter 方法中处理 null 值,避免空指针异常。
  • 有利于单元测试:与构造器注入类似,可以通过 Setter 方法注入模拟或替换依赖对象。

缺点:

  • 依赖关系不够明确:虽然比字段注入稍好一些,但依赖关系仍然不够直观。
  • 可能违反单一职责原则:如果 Setter 方法过多,可能会使类的职责不够单一。

3.为什么spring官方不推荐使用

在这里插入图片描述

1. 违反封装原则

直接在类的成员变量上使用@Autowired会导致类的内部状态对外部可见,这违反了面向对象编程中的封装原则。封装是面向对象编程的核心概念之一,它要求将对象的内部状态隐藏起来,只对外提供有限的接口进行交互。字段注入破坏了这种封装性,使得类的内部状态变得不可控,增加了潜在的风险。

2. 依赖关系不明确

字段注入将依赖关系隐藏在类的内部,使得类的依赖关系不明显。这会导致代码的可读性和可维护性下降。其他开发者在阅读代码时,很难一眼看出该类依赖于哪些其他类,从而增加了理解和修改代码的难度。

3. 难以进行单元测试

由于依赖的实例是自动注入的,测试时很难对依赖进行模拟或替换。这会增加单元测试的复杂性,并且可能导致测试覆盖率不足。相比之下,构造器注入或Setter方法注入使得依赖关系更加明确,便于在测试时通过构造器或Setter方法注入模拟对象。

4. 可能导致空指针异常

在字段注入的情况下,如果Spring容器中没有找到匹配的bean,那么注入的字段将保持为null。这可能导致在后续的代码执行中出现空指针异常(NPE),而这种异常在编译时是无法检测到的,只能在运行时才能发现。

5. 依赖注入的歧义性

如果Spring容器中存在多个相同类型的bean,并且你尝试使用@Autowired进行注入,那么Spring将无法确定应该注入哪一个bean,从而导致异常。虽然可以通过@Qualifier注解来指定要注入的bean的名称,但这增加了代码的复杂性和出错的可能性。

总结篇:

Spring官方不推荐使用@Autowired进行字段注入的主要原因是它违反了封装原则、导致依赖关系不明确、难以进行单元测试、可能导致空指针异常以及存在依赖注入的歧义性。为了编写更加健壮、易于理解和维护的代码,建议采用构造器注入或Setter方法注入作为依赖注入的替代方案。

在这里插入图片描述

我是杰叔叔,一名沪漂的码农,下期再会!

  • 12
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值