美文网首页
[Field injection is not recommen

[Field injection is not recommen

作者: BillSearchGates | 来源:发表于2021-01-25 01:02 被阅读0次

[Field injection is not recommended]为什么Spring的@Autowire不推荐注解在属性上?

背景

大家都知道spring中的bean可以使用@Autowire注解进行自动装配注入。其中有三种方式:

  • Constructor-based dependency injection 基于构造函数的依赖注入

  • Setter-based dependency injection 基于setter方法的依赖注入

  • Field-based dependency injection 基于属性字段的依赖注入

但是在Idea中,使用基于属性的注入(代码示例如下),会吃到“黄牌”warning

<pre mdtype="fences" cid="n6" contenteditable="true" lang="java" class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded md-focus" spellcheck="false" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px 0px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> @Autowire
private JdbcTemplate jdbcTemplate</pre>

warning信息:

Field injection is not recommended

Spring Team recommends: "Always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies".

为什么不推荐使用属性注入?

  1. 属性注入字段不允许用final修饰

基于属性字段的注入得到的bean不允许声明为final类型。只能通过基于构造函数的注入来声明不可变的bean(immutable bean)。

  1. 违反单一原则

如果过多地使用属性注入,很容易写很多个bean进行装配。而使用构造注入时,bean作为构造函数的参数,如果数量太多,更容易让人发现该类包含了太多协作者(违反了单一原则),进而将类拆分为更小、更易于维护的碎片。

  1. 和spring的IOC机制紧耦合

当你使用基于字段的依赖注入方式,完全把控制权全给Spring的IOC机制,在Spring容器之外,其它类无法重新设置某个注入的属性bean(反射机制除外)。

  1. 不方便对注入的bean进行校验

基于字段的依赖注入方式,类构造时并没有拿到被注入的属性的值,只有在被业务使用的时候才会拿到,不方便对该属性进行校验。假如使用构造注入,就可以在构造函数中进行校验,比如非空校验(避免NPE)。当然使用Spring的校验注解也可以实现。

  1. 隐藏了依赖关系

当你使用Spring的IOC的时候,被注入的类应当使用一些public类型(构造方法,和setter类型方法)的方法来向外界表达:我需要什么依赖。基于字段的依赖注入的方式,基本都是private形式的,外界不易理解所有依赖关系。

结论

避免使用基于字段的依赖注入,推荐使用基于构造函数基于setter的依赖注入。对于必需的依赖项,建议使用基于构造函数的注入,并声明为final类型,同时可以在构造函数中校验防止它们为null。对于可选的依赖项,建议使用基于Setter的注入

参考

Field injection is not recommended – Spring IOC

相关文章

网友评论

      本文标题:[Field injection is not recommen

      本文链接:https://www.haomeiwen.com/subject/pezvzktx.html