Spring Boot进阶(57):Spring中什么时候不要用@Autowired注入 | 超级详细,建议收藏

 1. 前言🔥

        注解@Autowired,相信对于我们Java开发者而言并不陌生吧,在SpringBoot或SpringCloud框架中使用那是非常的广泛。但是当我们使用IDEA编辑器开发代码的时候,经常会发现@Autowired 注解下面提示小黄线警告,我们把小鼠标悬停在注解上面,可以看到这个如下图所示的警告信息:

         这段警告是啥意思?为什么idea会给出 Field injection is not recommended 这样的警告呢?下面带着这些问题,一起来全面的了解下Spring中的三种注入方式以及他们之间在各方面的优劣。这将又会是干货满满的一期,全程无尿点不废话只抓重点教,具有非常好的学习效果,拿好小板凳准备就坐!希望学习的过程中大家认真听好好学,学习的途中有任何不清楚或疑问的地方皆可评论区留言或私信,bug菌将第一时间给予解惑,那么废话不多说,直接开整!Fighting!! 

2. 环境说明🔥

本地的开发环境:

  • 开发工具:IDEA 2021.3
  • JDK版本: JDK 1.8
  • Spring Boot版本:2.3.1 RELEASE
  • Maven版本:3.8.2

3. 三种注入方式🔥 

        我先给大家介绍一下Spring中的三种依赖注入方式,分别是Field Injection、Constructor Injection 和 Setter Injection,如下我分别进行重点介绍,同学们请看:

3.1 Field Injection

首先, @Autowired注解的一大使用场景非Field Injection莫属,具体代码演示如下:

@RestController
@RequestMapping("/user")
@Api(tags = "用户管理模块", description = "用户管理模块")
public class UserController {@Autowiredprivate UserService userService;@Autowiredprivate UserMapper userMapper;}

解读:这种注入方式通过Java的反射机制进行实现,所以private的成员也可以被注入具体的对象。

3.2 Constructor Injection 

Constructor Injection :构造器注入。Constructor Injection而言,是我们日常最为推荐的一种使用方式,具体代码演示如下:

@RestController
@RequestMapping("/user")
@Api(tags = "用户管理模块", description = "用户管理模块")
public class UserController {@Autowiredprivate UserMapper userMapper;private final UserService userService;public UserController(UserService userService) {this.userService = userService;}}

解读:这种注入方式很直接,通过对象构建的时候就把关系建立好,所以这种注入方式对对象创建的顺序会有要求,当然Spring会为你解决你的这种先后顺序的顾虑,除非你出现循环依赖问题,否则是不会抛出异常的。 

3.3 Setter Injection

        Setter Injection:成员变量的Setter函数上。其注入方式也会用到@Autowired注解,但使用方式与Field Injection是有所不同的,Field Injection是用在成员变量上,而使用Setter Injection方式注入是用在成员变量的Setter函数上。具体代码演示如下:

@RestController
@RequestMapping("/user")
@Api(tags = "用户管理模块", description = "用户管理模块")
public class UserController {private UserService userService;@Autowiredpublic void setUserService(UserService userService) {this.userService = userService;}@Autowiredprivate UserMapper userMapper;
}

解读:这种注入方式相比上面两种也很好理解,就是通过调用成员变量的set方法来注入想要使用的依赖对象,其他的都一样。

4. 三种依赖注入对比🔥

        经上文介绍,我们已在知道了Spring提供的三种依赖注入方式,但本文开头所抛出的问题:IDEA为什么不推荐Field Injection使用呢?为什么?

        这里我们可以从多个开发测试的考察角度来对比一下它们之间的优劣:

4.1 可靠性

主要从对象构建过程和使用过程中来衡量,看对象在各阶段的使用是否可靠作为依据进行分析:

  1. Field Injection:不可靠
  2. Constructor Injection:可靠
  3. Setter Injection:不可靠

由于构造函数有严格的构建顺序和不可变性,一旦构建就可用且不会被更改。

4.2 可维护性

主要从更容易阅读、分析依赖关系的角度作为依据进行分析:

  • Field Injection:差
  • Constructor Injection:好
  • Setter Injection:差

还是由于依赖关键的明确,从构造函数中可以显现的分析出依赖关系,对于我们如何去读懂关系和维护关系等更友好更浅显易懂。

4.3 可测试性

可测试性在复杂依赖关系的情况下,考察程序是否更容易编写单元测试作为依据进行分析:

  • Field Injection:差
  • Constructor Injection:好
  • Setter Injection:好

Constructor Injection和Setter Injection 的方式更容易Mock和注入对象,所以更容易开发者进行单元测试开发。

4.4 灵活性

灵活性主要根据开发实现时候的编码灵活性来判断:

  • Field Injection:好
  • Constructor Injection:差
  • Setter Injection:好

由于Constructor Injection对Bean的依赖关系设计有严格的顺序要求,所以这种注入方式不太灵活。相反 Field Injection 和 Setter Injection 这种方式使用起来就非常灵活,但由于其灵活带来了局面的混乱,也是一把双刃剑。

4.5 循环关系的检测

对于Bean之间是否存在循环依赖关系的检测能力,统计分析如下:

  • Field Injection:不检测
  • Constructor Injection:自动检测
  • Setter Injection:不检测

4.6 性能表现

不同的注入方式,对性能的影响分析如下:

  • Field Injection:启动快
  • Constructor Injection:启动慢
  • Setter Injection:启动快

性能上主要影响的就是启动时间,由于 Constructor Injection 有严格的顺序要求,所以会把启动时间拉长,这也是它的弊端之一。

4.7 总结

所以,综合上面各方面的比较,可以获得如下表格:

三种依赖注入的对比

最后,对于今天的问题的抛出,主要分析出两个结论,总结如下:

  1. 依赖注入的使用上Constructor Injection 是首选。
  2. 使用@Autowired注解的时候,要使用Setter Injection方式,这样代码更容易编写单元测试。

        好了,今天的学习就到这里!如果您学习过程中如遇困难?可以购买我们超高质量的专栏《滚雪球学Spring Boot》参与入门体验,更好的学习与进步!

5. 热文推荐🔥

滴~如下推荐【Spring Boot 进阶篇】的学习大纲,请小伙伴们注意查收。

Spring Boot进阶(01):Spring Boot 集成 Redis,实现缓存自由

Spring Boot进阶(02):使用Validation进行参数校验

Spring Boot进阶(03):如何使用MyBatis-Plus实现字段的自动填充

Spring Boot进阶(04):如何使用MyBatis-Plus快速实现自定义sql分页

Spring Boot进阶(05):Spring Boot 整合RabbitMq,实现消息队列服务

Spring Boot进阶(06):Windows10系统搭建 RabbitMq Server 服务端

Spring Boot进阶(07):集成EasyPoi,实现Excel/Word的导入导出

Spring Boot进阶(08):集成EasyPoi,实现Excel/Word携带图片导出

Spring Boot进阶(09):集成EasyPoi,实现Excel文件多sheet导入导出

Spring Boot进阶(10):集成EasyPoi,实现Excel模板导出成PDF文件

Spring Boot进阶(11):Spring Boot 如何实现纯文本转成.csv格式文件?

Spring Boot进阶(12):Spring Boot 如何获取Excel sheet页的数量?

Spring Boot进阶(13):Spring Boot 如何获取@ApiModelProperty(value = “序列号“, name = “uuid“)中的value值name值?

Spring Boot进阶(14):Spring Boot 如何手动连接库并获取指定表结构?一文教会你

Spring Boot进阶(15):根据数据库连接信息指定分页查询表结构信息

Spring Boot进阶(16):Spring Boot 如何通过Redis实现手机号验证码功能?

Spring Boot进阶(17):Spring Boot如何在swagger2中配置header请求头等参数信息

Spring Boot进阶(18):SpringBoot如何使用@Scheduled创建定时任务?

Spring Boot进阶(19):Spring Boot 整合ElasticSearch

Spring Boot进阶(20):配置Jetty容器

Spring Boot进阶(21):配置Undertow容器

Spring Boot进阶(22):Tomcat与Undertow容器性能对比分析

Spring Boot进阶(23):实现文件上传

Spring Boot进阶(24):如何快速实现多文件上传?

Spring Boot进阶(25):文件上传的单元测试怎么写?

Spring Boot进阶(26):Mybatis 中 resultType、resultMap详解及实战教学

Spring Boot进阶(27):Spring Boot 整合 kafka(环境搭建+演示)

Spring Boot进阶(28):Jar包Linux后台启动部署及滚动日志查看,日志输出至实体文件保存

Spring Boot进阶(29):如何正确使用@PathVariable,@RequestParam、@RequestBody等注解?不会我教你,结合Postman演示

Spring Boot进阶(30):@RestController和@Controller 注解使用区别,实战演示

...

6. 文末🔥

        如果想系统性的学习Spring Boot,小伙伴们直接订阅bug菌专门为大家创建的Spring Boot专栏《滚雪球学Spring Boot》从入门到精通,从无到有,从零到一!以知识点+实例+项目的学习模式由浅入深对Spring Boot框架进行学习&使用。

        如果你有一定的基础却又想精进Spring Boot,那么《Spring Boot进阶实战》将会是你的最好的选择;此栏进行知识点+实例+项目的学习方式全面深入框架剖析及各种高阶玩法,励志打造全网最全最新springboot学习专栏,投资学习自己性价比最高。

        本文涉及所有源代码,均已上传至github开源,供同学们一对一参考,GitHub,同时,原创开源不易,欢迎给个star🌟,想体验下被加Star的感jio,非常感谢 ❗

       我是bug菌,一名想走👣出大山改变命运的程序猿。接下来的路还很长,都等待着我们去突破、去挑战。来吧,小伙伴们,我们一起加油!未来皆可期,fighting!

关注公众号,获取最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板等硬核资源

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1507.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【多线程】(五)工厂模式和线程池

文章目录 一、工厂模式二、线程池2.1 什么是线程池2.2 Executor 工厂类创建线程池2.3 ThreadPoolExecutor类创建线程池 三、线程池的实现 一、工厂模式 在Java中,工厂模式是一种创建对象的设计模式,它通过提供一个共同的接口来实例化对象,而…

Redis【实战篇】---- 分布式锁

Redis【实战篇】---- 分布式锁 1. 基本原理和实现方式对比2. Redis分布式锁的实现核心思路3. 实现分布式锁版本一4. Redis分布式锁误删情况说明5. 解决Redis分布式锁误删问题6. 分布式锁的原子性问题7. Lua脚本解决多条命令原子性问题8. 利用Java代码调试Lua脚本改造分布式锁 1…

css背景毛玻璃效果

一、结论:通过 css 的 backdrop-filter 属性设置滤镜函数 blur 一般会是有 背景色、透明度 的容器,如: /* 宽高等其他设置这里省略没写 */ background:rgba(3, 87, 255, 0.3); backdrop-filter: blur(10px);二、backdrop-filter 的其他用法…

Mysql教程(四):DML学习

Mysql教程(四):DML学习 前言 DML-介绍 DML英文全称是Data Manipulation Language数据库操作语言,用来对数据库中表的数据记录进行增删改查。 添加数据(INSERT)修改数据(UPDATE)删除…

走访慰问空巢老人,连接传递浓浓温情

为了弘扬中华民族尊老、敬老、爱老的优良传统,让老人们感受到政府和社会的温暖,在“端午”来临之际,思南县青年志愿者协会联合思南县民慈社会工作服务中心、思南县小荧星幼儿园、思南县小英豪幼儿园到大河坝镇天坝村开展“走访慰问空巢老人&a…

docker 安装minIO服务器-以及数据迁移

--------------docker安装minIO-------------- 1.安装docker环境略 2.安装minIO镜像 docker pull minio/minio 3.运行MinIO docker run -p 9000:9000 -p 9090:9090 \ --name minio \ -d --restartalways \ -e "MINIO_ACCESS_KEYadmin" \ -e "MINIO_SECRET…

springboot整合eureka、config搭建注册中心和配置中心

目录 一 、springboot整合eureka实现注册中心 二、springboot整合config实现配置中心 三、从配置中心拉取配置 这篇文章详细介绍怎么通过eureka和config分别搭建一个注册中心和配置中心的服务。 一 、springboot整合eureka实现注册中心 1、创建一个springboot项目&#xff…

LRU 算法,但 get 和 put 必须 O(1),用哈希表

https://leetcode.cn/problems/lru-cache/ 题目有key、value的,直接就上map了 结果:😅 仔细一看,原来要 get 和 put 必须 O(1) 只能抛弃树型数据结构了 线性的数据结构也可以吧,如果可以构造出一个队列&#xff0c…

Appium+python自动化(十一)- 元素定位- 下卷超详解)

1、 List定位 List故名思义就是一个列表,在python里面也有list这一个说法,如果你不是很理解什么是list,这里暂且理解为一个数组或者说一个集合。首先一个list是一个集合,那么他的个数也就成了不确定性,所以这里需要用复…

AI一点通:使用Pinecone、Langchain和OpenAI嵌入构建强大的文本搜索系统

在当今数据驱动的世界中,企业和开发人员经常需要实现强大的文本搜索功能。传统的搜索算法在处理大量非结构化文本数据时可能无法提供最优结果。这就是Pinecone、Langchain和OpenAI服务发挥作用的地方。在本博客文章中,我们将探讨设置和利用这些工具来构建…

【InsCode Stable Diffusion 美图活动一期】生成着玩

此为内容创作模板,请按照格式补充内容,在发布之前请将不必要的内容删除 一、 Stable Diffusion 模型在线使用地址: https://inscode.csdn.net/inscode/Stable-Diffusion 二、模型相关版本和参数配置: 三、图片生成提示词与反向…

春秋云境—Initial

文章目录 春秋云境—Initial一、前期准备1、靶标介绍2、相关设备 二、WEB渗透1、ThinkPHP RCE(1)、打开网站(2)、检测漏洞 2、蚁剑连接3、sudo提权4、frpc代理5、fsacn扫描 三、后渗透1、信呼OA RCE(1)、1.…

npm安装依赖报错Unexpected token ‘.‘ 处理

1. 问题 在用nvm切换高版本node版本之后npm install安装项目依赖时报错如下: npm ERR! Unexpected token . 日志信息如下: 报错信息量很少,但是跟高版本node环境下安装依赖有关系。 2. 解决思路 安装低版本的node环境运行项目&#xff…

C++ 多线程编程

1 多线程编程简介 说到多线程编程,就不得不提并行和并发,多线程是实现并发和并行的一种手段。 并行是指两个或多个独立的操作同时进行。 并发是指一个时间段内执行多个操作。 在单核时代,多个线程是并发的,在一个时间段内轮流…

RabbitMQ死信交换机、TTL及延迟队列

一,死信交换机 1,什么是死信交换机 了解死信交换机之前我们先来了解一下什么是死信,当一个队列满足下面的三种情况的时候我们一般称为死信(dead letter): 消费者使用basic.reject或 basic.nack声明消费失…

小白入门深度学习 | 6-6:Inception v3 算法原理

一、理论基础 Inceptionv3论文:Rethinking the Inception Architecture for Computer Vision.pdf Inception v3由谷歌研究员Christian Szegedy等人在2015年的论文《Rethinking the Inception Architecture for Computer Vision》中提出。Inception v3是Inception网络系列的第三…

petalinux 无法通过SDK进行TCF调试

IP地址设置没问题 但是无法进行DEBUG 原因是没有开启debug模式,做下图设置重新编译程序生成BOOT.bin即可

追踪 Kubernetes 中的 DNS 查询

在过去的文章中,我们曾 追踪过 Kubernetes 中的网络数据包,这篇文章将追踪 Kubernetes 中的 DNS 查询。 让我们以在 Pod 中解析 Service 完全限定域名(FQDN) foo.bar.svc.cluster.local 为例。 在开始之前,先回顾下 …

微信小程序的目录解析--【浅入深出系列001外篇】

浅入深出系列总目录在000集 如何0元学微信小程序–【浅入深出系列000】 文章目录 本系列校训学习资源的选择先说总目录经常碰到的文件(目录)最最常见的目录pages次最常用的就是images 目录 操作起来真正的操作 配套资源 本系列校训 用免费公开视频,卷…

Nginx问题汇总

为什么Nginx性能这么高? 主要是因为他的事件处理机制:异步非阻塞事件处理机制(事件驱动的异步模型):运用了epoll模型,Nginx 会创建一些事件对象,然后将这些事件对象注册到事件驱动器中。当事件…