在使用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. [转]12个scp传输文件的命令栗子

    原文地址: https://www.cnblogs.com/voidy/p/4215891.html copy原文是为了修改部分错误以及便于记录自己的笔记.英文原文点:这里 安全复制 Scp(Secu ...

  2. OSI与TCP/IP各层的结构与功能,都有哪些协议?

    学习计算机⽹络时我们⼀般采⽤折中的办法,也就是中和 OSI 和 TCP/IP 的优点,采⽤⼀种只有 五层协议的体系结构,这样既简洁⼜能将概念阐述清楚. 结合互联⽹的情况,⾃上⽽下地,⾮常简要的介绍⼀下 ...

  3. NTFS安全权限

    一.NTFS权限概述 1.通过设置NTFS权限,实现不同的用户访问不同的对象的权限 2.分配了真确的访问权限后,用户才能访问其资源 3.设置权限防止资源被篡改.删除 二.文件系统概述 文件系统即在外部 ...

  4. 高校表白App-团队冲刺第二天

    今天要做什么 今天要把昨天的activity进行完善,并且加上计时跳转的功能,将其设置为主页面,设置两种跳转功能. 遇到的问题 今天没遇到什么大的问题,只是在进行编写的时候,又出现了R文件无法找到的情 ...

  5. 关键字替代符号C++

    不知从什么时候的哪里我看到了一个and关键字,心想这是个什么玩意...然后知道它相当于&&,于是开启了罪恶的生涯-- 替代关键字,似乎可读性更好,但是有些编译器可能会无法识别(eg.M ...

  6. py3射击小游戏

    关于py3面向对象的小Demo,欢迎 交流. class Person(object):#声明人类 def __init__(self,name): self.name = name self.gun ...

  7. 货币兑换问题(动态规划法)——Python实现

      # 动态规划法求解货币兑换问题 # 货币系统有 n 种硬币,面值为 v1,v2,v3...vn,其中 v1=1,使用总值为money的钱与之兑换,求如何使硬币的数目最少,即 x1,x2,x3... ...

  8. tomcat与springmvc 结合 之---第19篇(下,补充) springmvc 加载.xml文件的bean标签的过程

    writedby 张艳涛,上一篇写了springmvc对<mvc:annoXXXX/>标签的解析过程,其实是遗漏重要的细节,因为理解的不深入吧 今天接着解析<bean>标签 & ...

  9. php中英文字符串转字母转大小写

    <?php //转小写 function lowercase($a){ $b = str_split($a, 1); $r = ''; foreach($b as $v){ $v = ord($ ...

  10. 用python将word转pdf、doc转docx等

    word ==> pdf def doc2pdf(file_path): """ word格式转换doc|docx ==> pdf :return: &quo ...