乐趣区

关于java:为什么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 InjectionSetter Injection 的形式更容易 Mock 和注入对象,所以更容易实现单元测试。

灵活性

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

  • Field Injection:很灵便
  • Constructor Injection:不灵便
  • Setter Injection:很灵便

因为 Constructor Injection 对 Bean 的依赖关系设计有严格的程序要求,所以这种注入形式不太灵便。相同 Field InjectionSetter 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 也不会给出正告了。同时,也侧面也反映了,可测试性的重要位置啊!

总结

最初,对于明天的问题探讨,咱们给出两个论断,不便大家记忆:

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

好了,明天的学习就到这里!如果您学习过程中如遇艰难?能够退出咱们超高品质的 Spring 技术交换群,参加交换与探讨,更好的学习与提高!

原创不易,欢送转发分享本篇内容,您的反对是我保持的能源!

欢送关注我的公众号:程序猿 DD,分享其余中央看不到的常识与思考

退出移动版