@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,分享其余中央看不到的常识与思考