Spring中为什么不建议使用字段注入
在使用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中为什么不建议使用字段注入的更多相关文章
- 轻松了解Spring中的控制反转和依赖注入(二)
紧接上一篇文章<轻松了解Spring中的控制反转和依赖注入>讲解了SpringIOC和DI的基本概念,这篇文章我们模拟一下SpringIOC的工作机制,使我们更加深刻的理解其中的工作. 类 ...
- Spring中的控制反转和依赖注入
Spring中的控制反转和依赖注入 原文链接:https://www.cnblogs.com/xxzhuang/p/5948902.html 我们回顾一下计算机的发展史,从最初第一台计算机的占地面积达 ...
- 由一个RABBITMQ监听器死循环引出的SPRING中BEAN和MAPPER接口的注入问题
1 @Slf4j 2 @RestController 3 @Component 4 public class VouchersReceiverController implements Message ...
- 轻松了解Spring中的控制反转和依赖注入(一)
我们回顾一下计算机的发展史,从最初第一台计算机的占地面积达170平方米,重达30吨,到现如今的个人笔记本,事物更加轻量功能却更加丰富,这是事物发展过程中的一个趋势,在技术领域中同样也是如此,企业级Ja ...
- Spring中的依赖查找和依赖注入
作者:Grey 原文地址: 语雀 博客园 依赖查找 Spring IoC 依赖查找分为以下几种方式 根据 Bean 名称查找 实时查找 延迟查找 根据 Bean 类型查找 单个 Bean 对象 集合 ...
- Spring中如何动态注入Bean实例教程
前言 在Spring中提供了非常多的方式注入实例,但是由于在初始化顺序的不同,基于标注的注入方式,容易出现未被正确注入成功的情况. 本文将介绍一种在实际项目中基于动态的方式来提取Spring管理的Be ...
- Spring中依赖注入的四种方式
在Spring容器中为一个bean配置依赖注入有三种方式: · 使用属性的setter方法注入 这是最常用的方式: · 使用构造器注入: · 使用Filed注入(用于注解方式). 使用属性的sett ...
- spring中bean配置和bean注入
1 bean与spring容器的关系 Bean配置信息定义了Bean的实现及依赖关系,Spring容器根据各种形式的Bean配置信息在容器内部建立Bean定义注册表,然后根据注册表加载.实例化Bean ...
- IoC 依赖注入、以及在Spring中的实现
资源来自网络: 去年火得不行的Spring框架,一般的书籍都会从IoC和AOP开始介绍起,这个IoC概念,个人感觉资料里都写得让人看得有些痛苦,所谓IoC,就是控制反转(Inversion of Co ...
随机推荐
- 欧拉函数&筛法 模板
https://blog.csdn.net/Lytning/article/details/24432651 记牢通式 =x((p1-1)/p1) * ((p2-1)/p2)....((pn-1 ...
- PHP观察者模式 (转)
观察者模式(Observer),当一个对象的状态发生改变时,依赖他的对象会全部收到通知,并自动更新. 场景:一个事件发生后,要执行一连串更新操作.传统的编程方式,就是在事件的代码之后直接加入处理逻 ...
- Jmeter之cokie管理器和http默认值
根据上文中,都配置好以后就可以开始启动了,点击启动,线程组里面就会开始记录你的网页请求.这里使用CNode网站做测试.我分别记录进行了"登入","话题创建",& ...
- ELK处理Spring Boot 日志,妙!
在排查线上异常的过程中,查询日志总是必不可缺的一部分.现今大多采用的微服务架构,日志被分散在不同的机器上,使得日志的查询变得异常困难. 工欲善其事,必先利其器.如果此时有一个统一的实时日志分析平台,那 ...
- Pytorch的模型加速方法:Dataparallel (DP) 和 DataparallelDistributedparallel (DDP)
Dataparallel 和 DataparallelDistributed 的区别 一.Dataparallel(DP) 1.1 Dartaparallel 的使用方式 Dataparallel 的 ...
- C语言:猴子吃桃问题
//猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个. //第二天早上又将第一天剩下的桃子吃掉一半,有多吃了一个.以后每天早上都吃了前一天剩下的一半零一个. //到第 10 ...
- 学习 CLR 源码:连续内存块数据操作的性能优化
目录 C# 原语类型 1,利用 Buffer 优化数组性能 2,BinaryPrimitives 细粒度操作字节数组 提高代码安全性 3,BitConverter.MemoryMarshal 4,Ma ...
- Pandas高级教程之:自定义选项
目录 简介 常用选项 get/set 选项 经常使用的选项 最大展示行数 超出数据展示 最大列的宽度 显示精度 零转换的门槛 列头的对齐方向 简介 pandas有一个option系统可以控制panda ...
- CSAPP:bomblab
BOMBLAB实验总结 CSAPP实验BOMB,很头疼,看不懂,勉强做完了. 答案是这样的: Border relations with Canada have never been better. ...
- 解决pip下载速度慢的问题
解决链接:https://blog.csdn.net/u013901768/article/details/82343512 感谢这位博主的分享. 博客内容如下: 1. 安装时强制使用国内源进行安装, ...