在使用Idea中通过注解注入字段时是否遇见过这样一个提示:

Field injection is not recommended(不推荐使用字段注入)

一. 什么是字段注入,Spring中依赖注入的方式有哪些?

在Spring中依赖注入有三大类:字段注入、构造器注入、Setter方法注入。

字段注入是将Bean作为字段注入到类中,也是最方便,用的最多的注入方式。

二. 官方为什么不推荐使用字段注入

首先来看字段注入

@RestController
public class TestHandleController {

@Autowired
TestHandleService testHandleService;

public void helloTestService(){
testHandleService.hello();
}
}

字段注入的非常的简便,通过以上代码我们就可以轻松的使用TestHandleService类,但是如果变成下面这样呢:

TestHandleController testHandle = new TestHandleController();
testHandle.helloTestService();

这样执行结果为空指针异常,这就是字段注入的第一个问题:对象的外部可见性,无法在容器外部实例化TestHandleService,类和容器的耦合度过高,无法脱离容器访问目标对象。

接下来看第二段代码:

public class TestA(){

@Autowired
private TestB testB;

}

public class TestB(){

@Autowired
private TestA testA;

}

这段代码在idea中不会报任何错误,但是当你启动项目时会发现报错,大致意思是:创建Bean失败,原因是当前Bean已经作为循环引用的一部分注入到了其他Bean中。

这就是字段注入的第二个问题:可能导致循环依赖

字段注入还有第三个问题:无法设置注入的对象为final,也无法注入静态变量,原因是变量必须在类实例化进行初始化。

整理一下,字段注入可能引起的三个问题:

1. 对象的外部可见性

2. 可能导致循环依赖

3. 无法设置注入的对象为final,也无法注入静态变量


接下来看构造器注入--官方推荐的注入方式

使用形式也很简单:

private TestHandleService testHandleService;

@Autowired
public TestHandleController(TestHandleService testHandleService){
this.testHandleService = testHandleService;
}

通过构造器的方式将Bean注入到字段中。

构造器注入能够保证注入的组件不可变,并且确保需要的依赖不为空。

这样就可以将变量设置为final,并且传递的肯定是一个对象,避免出现空指针异常。

若是出现字段注入中循环依赖的问题,在项目启动时Spring会非常形象的将错误抛出来:

Description:

The dependencies of some of the beans in the application context form a cycle:

testContrtoller (field private com.example.designstudy.service.TestService com.example.designstudy.controller.TestContrtoller.testService)
┌─────┐
| testService defined in file [D:\design-study\target\classes\com\example\designstudy\service\TestService.class]
↑ ↓
| testHandleServiceImpl defined in file [D:\design-study\target\classes\com\example\designstudy\service\impl\TestHandleServiceImpl.class]
└─────┘

显而易见的发现错误的地方。

由此可见,字段注入的三大问题都能解决,但是构造器注入就没有其他问题了吗?

答案肯定是否定的,当依赖的对象很多时,需要严格按照构造器的顺序去填写依赖的对象,这将导致代码可读性和可维护性变得很差。

这时候可以引入Setter方法进行注入,Setter方法和构造器注入很像,不过Setter更具有可读性。

并且使用Setter方法注入可以实现按需注入,不使用的对象不需要想构造器注入一样强制注入。

总结一下三种注入方式:

构造器注入适用于强制对象注入

Setter注入适合可选对象注入

字段注入方式应该尽量避免,因为对象无法脱离容器独立运行(话虽这么说,但我还是字段注入用得多,因为方便啊 [/狗头])

Spring中为什么不建议使用字段注入的更多相关文章

  1. 轻松了解Spring中的控制反转和依赖注入(二)

    紧接上一篇文章<轻松了解Spring中的控制反转和依赖注入>讲解了SpringIOC和DI的基本概念,这篇文章我们模拟一下SpringIOC的工作机制,使我们更加深刻的理解其中的工作. 类 ...

  2. Spring中的控制反转和依赖注入

    Spring中的控制反转和依赖注入 原文链接:https://www.cnblogs.com/xxzhuang/p/5948902.html 我们回顾一下计算机的发展史,从最初第一台计算机的占地面积达 ...

  3. 由一个RABBITMQ监听器死循环引出的SPRING中BEAN和MAPPER接口的注入问题

    1 @Slf4j 2 @RestController 3 @Component 4 public class VouchersReceiverController implements Message ...

  4. 轻松了解Spring中的控制反转和依赖注入(一)

    我们回顾一下计算机的发展史,从最初第一台计算机的占地面积达170平方米,重达30吨,到现如今的个人笔记本,事物更加轻量功能却更加丰富,这是事物发展过程中的一个趋势,在技术领域中同样也是如此,企业级Ja ...

  5. Spring中的依赖查找和依赖注入

    作者:Grey 原文地址: 语雀 博客园 依赖查找 Spring IoC 依赖查找分为以下几种方式 根据 Bean 名称查找 实时查找 延迟查找 根据 Bean 类型查找 单个 Bean 对象 集合 ...

  6. Spring中如何动态注入Bean实例教程

    前言 在Spring中提供了非常多的方式注入实例,但是由于在初始化顺序的不同,基于标注的注入方式,容易出现未被正确注入成功的情况. 本文将介绍一种在实际项目中基于动态的方式来提取Spring管理的Be ...

  7. Spring中依赖注入的四种方式

    在Spring容器中为一个bean配置依赖注入有三种方式: · 使用属性的setter方法注入  这是最常用的方式: · 使用构造器注入: · 使用Filed注入(用于注解方式). 使用属性的sett ...

  8. spring中bean配置和bean注入

    1 bean与spring容器的关系 Bean配置信息定义了Bean的实现及依赖关系,Spring容器根据各种形式的Bean配置信息在容器内部建立Bean定义注册表,然后根据注册表加载.实例化Bean ...

  9. IoC 依赖注入、以及在Spring中的实现

    资源来自网络: 去年火得不行的Spring框架,一般的书籍都会从IoC和AOP开始介绍起,这个IoC概念,个人感觉资料里都写得让人看得有些痛苦,所谓IoC,就是控制反转(Inversion of Co ...

随机推荐

  1. 欧拉函数&筛法 模板

    https://blog.csdn.net/Lytning/article/details/24432651    记牢通式 =x((p1-1)/p1) * ((p2-1)/p2)....((pn-1 ...

  2. PHP观察者模式 (转)

      观察者模式(Observer),当一个对象的状态发生改变时,依赖他的对象会全部收到通知,并自动更新. 场景:一个事件发生后,要执行一连串更新操作.传统的编程方式,就是在事件的代码之后直接加入处理逻 ...

  3. Jmeter之cokie管理器和http默认值

    根据上文中,都配置好以后就可以开始启动了,点击启动,线程组里面就会开始记录你的网页请求.这里使用CNode网站做测试.我分别记录进行了"登入","话题创建",& ...

  4. ELK处理Spring Boot 日志,妙!

    在排查线上异常的过程中,查询日志总是必不可缺的一部分.现今大多采用的微服务架构,日志被分散在不同的机器上,使得日志的查询变得异常困难. 工欲善其事,必先利其器.如果此时有一个统一的实时日志分析平台,那 ...

  5. Pytorch的模型加速方法:Dataparallel (DP) 和 DataparallelDistributedparallel (DDP)

    Dataparallel 和 DataparallelDistributed 的区别 一.Dataparallel(DP) 1.1 Dartaparallel 的使用方式 Dataparallel 的 ...

  6. C语言:猴子吃桃问题

    //猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个. //第二天早上又将第一天剩下的桃子吃掉一半,有多吃了一个.以后每天早上都吃了前一天剩下的一半零一个. //到第 10 ...

  7. 学习 CLR 源码:连续内存块数据操作的性能优化

    目录 C# 原语类型 1,利用 Buffer 优化数组性能 2,BinaryPrimitives 细粒度操作字节数组 提高代码安全性 3,BitConverter.MemoryMarshal 4,Ma ...

  8. Pandas高级教程之:自定义选项

    目录 简介 常用选项 get/set 选项 经常使用的选项 最大展示行数 超出数据展示 最大列的宽度 显示精度 零转换的门槛 列头的对齐方向 简介 pandas有一个option系统可以控制panda ...

  9. CSAPP:bomblab

    BOMBLAB实验总结 CSAPP实验BOMB,很头疼,看不懂,勉强做完了. 答案是这样的: Border relations with Canada have never been better. ...

  10. 解决pip下载速度慢的问题

    解决链接:https://blog.csdn.net/u013901768/article/details/82343512 感谢这位博主的分享. 博客内容如下: 1. 安装时强制使用国内源进行安装, ...