为什么IDEA不推荐你使用@Autowired ?
@Autowired
注解相信每个Spring开发者都不陌生了!在DD的Spring Boot基础教程和Spring Cloud基础教程中也都经常会出现。
但是当我们使用IDEA写代码的时候,经常会发现@Autowired
注解下面是有小黄线的,我们把小鼠标悬停在上面,可以看到这个如下图所示的警告信息:
那么为什么IDEA会给出Field injection is not recommended
这样的警告呢?
下面带着这样的问题,一起来全面的了解下Spring中的三种注入方式以及他们之间在各方面的优劣。
Spring中的三种依赖注入方式
Field Injection
@Autowired
注解的一大使用场景就是Field Injection
。
具体形式如下:
@Controller
public class UserController {
@Autowired
private UserService userService;
}
这种注入方式通过Java的反射机制实现,所以private的成员也可以被注入具体的对象。
Constructor Injection
Constructor Injection
是构造器注入,是我们日常最为推荐的一种使用方式。
具体形式如下:
@Controller
public class UserController {
private final UserService userService;
public UserController(UserService userService){
this.userService = userService;
}
}
这种注入方式很直接,通过对象构建的时候建立关系,所以这种方式对对象创建的顺序会有要求,当然Spring会为你搞定这样的先后顺序,除非你出现循环依赖,然后就会抛出异常。
Setter Injection
Setter Injection
也会用到@Autowired
注解,但使用方式与Field Injection
有所不同,Field Injection
是用在成员变量上,而Setter Injection
的时候,是用在成员变量的Setter函数上。
具体形式如下:
@Controller
public class UserController {
private UserService userService;
@Autowired
public void setUserService(UserService userService){
this.userService = userService;
}
}
这种注入方式也很好理解,就是通过调用成员变量的set方法来注入想要使用的依赖对象。
三种依赖注入的对比
在知道了Spring提供的三种依赖注入方式之后,我们继续回到本文开头说到的问题:IDEA为什么不推荐使用Field Injection
呢?
我们可以从多个开发测试的考察角度来对比一下它们之间的优劣:
可靠性
从对象构建过程和使用过程,看对象在各阶段的使用是否可靠来评判:
Field Injection
:不可靠Constructor Injection
:可靠Setter Injection
:不可靠
由于构造函数有严格的构建顺序和不可变性,一旦构建就可用,且不会被更改。
可维护性
主要从更容易阅读、分析依赖关系的角度来评判:
Field Injection
:差Constructor Injection
:好Setter Injection
:差
还是由于依赖关键的明确,从构造函数中可以显现的分析出依赖关系,对于我们如何去读懂关系和维护关系更友好。
可测试性
当在复杂依赖关系的情况下,考察程序是否更容易编写单元测试来评判
Field Injection
:差Constructor Injection
:好Setter Injection
:好
Constructor Injection
和Setter Injection
的方式更容易Mock和注入对象,所以更容易实现单元测试。
灵活性
主要根据开发实现时候的编码灵活性来判断:
Field Injection
:很灵活Constructor Injection
:不灵活Setter Injection
:很灵活
由于Constructor Injection
对Bean的依赖关系设计有严格的顺序要求,所以这种注入方式不太灵活。相反Field Injection
和Setter Injection
就非常灵活,但也因为灵活带来了局面的混乱,也是一把双刃剑。
循环关系的检测
对于Bean之间是否存在循环依赖关系的检测能力:
Field Injection
:不检测Constructor Injection
:自动检测Setter Injection
:不检测
性能表现
不同的注入方式,对性能的影响
Field Injection
:启动快Constructor Injection
:启动慢Setter Injection
:启动快
主要影响就是启动时间,由于Constructor Injection
有严格的顺序要求,所以会拉长启动时间。
所以,综合上面各方面的比较,可以获得如下表格:
结果一目了然,Constructor Injection
在很多方面都是优于其他两种方式的,所以Constructor Injection
通常都是首选方案!
而Setter Injection
比起Field Injection
来说,大部分都一样,但因为可测试性更好,所以当你要用@Autowired
的时候,推荐使用Setter Injection
的方式,这样IDEA也不会给出警告了。同时,也侧面也反映了,可测试性的重要地位啊!
总结
最后,对于今天的问题讨论,我们给出两个结论,方便大家记忆:
- 依赖注入的使用上,
Constructor Injection
是首选。 - 使用
@Autowired
注解的时候,要使用Setter Injection
方式,这样代码更容易编写单元测试。
好了,今天的学习就到这里!如果您学习过程中如遇困难?可以加入我们超高质量的Spring技术交流群,参与交流与讨论,更好的学习与进步!
原创不易,欢迎转发分享本篇内容,您的支持是我坚持的动力!
欢迎关注我的公众号:程序猿DD,分享外面看不到的干货与思考!
为什么IDEA不推荐你使用@Autowired ?的更多相关文章
- SpringBoot系列: 理解 Spring 的依赖注入(二)
==============================Spring 容器中 Bean 的名称==============================声明 bean 有两个方式, 一个是 @B ...
- Dubbo学习系列之十二(Quartz任务调度)
Quartz词义为"石英"水晶,然后聪明的人类利用它发明了石英手表,因石英晶体在受到电流影响时,它会产生规律的振动,于是,这种时间上的规律,也被应用到了软件界,来命名了一款任务调度 ...
- Spring第四天,BeanPostProcessor源码分析,彻底搞懂IOC注入及注解优先级问题!
- Spring Boot 2.6.0正式发布:默认禁止循环依赖、增强Docker镜像构建...
昨天,Spring官方正式发布了Spring Boot今年最后一个特性版本:2.6.0 同时,也宣布了2.4.x版本的终结. 那么这个新版本又带来了哪些新特性呢?下面就一起跟着DD来看看吧! 重要特性 ...
- spring-boot关于spring全注解IOC
什么是IOC容器: Spring IoC 容器是一个管理Bean 的容器,在S pring 的定义中,它要求所有的IoC 容器都需要实现接口BeanFactory ,它是一个顶级容器接口 IoC 是一 ...
- 想用@Autowired注入static静态成员?官方不推荐你却还偏要这么做
生命太短暂,不要去做一些根本没有人想要的东西.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习 ...
- 推荐使用@Resource,不推荐使用@Autowired
@Autowired 默认根据ByType, 当一个类有两个对象的时候,会报错. @Resource 默认是ByName,可以精准的找到<bean>的配置项. jar包推送,应该级联推送: ...
- @Autowired的使用:推荐对构造函数进行注释
在编写代码的时候,使用@Autowired注解是,发现IDE报的一个警告,如下: Spring Team recommends "Always use constructor based d ...
- @Autowired的使用--Spring规范解释,推荐对构造函数进行注释
一 在编写代码的时候,使用@Autowired注解是,发现IDE报的一个警告,如下: Spring Team recommends "Always use constructor based ...
随机推荐
- nuxt打包等注意事项
打包步骤: 1.首先执行 npm run build 2.将打包好的 .nuxt static nuxt.config.js package.json 这四个文件丢到服务器的某个文件夹中,在服务器上安 ...
- (转载https://segmentfault.com/a/1190000016313947)了解RestFul Api架构风格设计
最近几年REST API越来越流行,特别是随着微服务的概念被广泛接受和应用,很多Web Service都使用了REST API. REST是HTTP规范主要编写者之一的Roy Fielding提出的, ...
- Java基础系列(19)- Switch结构
package struct; public class SwitchDemo01 { //case穿透 //switch 匹配一个具体的值 public static void main(Strin ...
- dotnet 读 WPF 源代码笔记 布局时 Arrange 如何影响元素渲染坐标
大家是否好奇,在 WPF 里面,对 UIElement 重写 OnRender 方法进行渲染的内容,是如何受到上层容器控件的布局而进行坐标偏移.如有两个放入到 StackPanel 的自定义 UIEl ...
- 在eclipse上配置tomcat(包括解决找不到server,配置8.0以上版本)
下载安装eclipse普通eclipse最多只支持到tomcat v 7,要想使用8以上的tomcat,就需要下载最新版本的Eclipse IDE,安装时 选择 Eclipse IDE for Ent ...
- Fabric SSH链接时关于找不到主机的问题
先上一段简单的fabric代码: from __future__ import with_statementfrom fabric.api import *env.user = 'zhangsan'e ...
- CentOS7 Docker容器无法ping通宿主机ip问题解决记录
Docker服务部署启动容器发现docker容器内访问宿主机IP不通,于是进入容器内ping宿主机IP,发现无法ping通,容器IP为172.17.0.2,于是继续ping172.17.0.1也不通, ...
- HCNP Routing&Switching之BGP基础
前文我们了解了路由注入带来的问题以及解决方案相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15362604.html:今天我们来学习下新的路由协议BG ...
- node-gyp项目命名BUG
当我们编写node原生模块的时候,免不了对node-gyp项目进行命名,在node-gyp进行build的时候,会跟binding.gyp配置文件中的target_name生成对应的原生模块.但是,如 ...
- 高德 Serverless 平台建设及实践
作者 | 邓学祥(祥翼) 来源 | Serverless 公众号 高德从 FY21 财年开始启动 Serverless 建设,至今一年了,高德 Serverless 业务的峰值超过十万 qps 量级, ...