当我们在使用依赖注入的时候,通常有三种方式:

1.通过构造器来注入;

2.通过setter方法来注入;

3.通过filed变量来注入;

那么他们有什么区别吗?应该选择哪种方式更好?

三种方式的区别小结:

1.基于constructor的注入,会固定依赖注入的顺序;该方式不允许我们创建bean对象之间的循环依赖关系,这种限制其实是一种利用构造器来注入的益处 - 当你甚至没有注意到使用setter注入的时候,Spring能解决循环依赖的问题;

2.基于setter的注入,只有当对象是需要被注入的时候它才会帮助我们注入依赖,而不是在初始化的时候就注入;另一方面如果你使用基于constructor注入,CGLIB不能创建一个代理,迫使你使用基于接口的代理或虚拟的无参数构造函数。

3.相信很多同学都选择使用直接在成员变量上写上注解来注入,正如我们所见,这种方式看起来非常好,精短,可读性高,不需要多余的代码,也方便维护;

缺点:

1.当我们利用constructor来注入的时候,比较明显的一个缺点就是:假如我们需要注入的对象特别多的时候,我们的构造器就会显得非常的冗余、不好看,非常影响美观和可读性,维护起来也较为困难;

2.当我们选择setter方法来注入的时候,我们不能将对象设为final的;

3.当我们在field变量上来实现注入的时候

a.这样不符合JavaBean的规范,而且很有可能引起空指针;

b.同时也不能将对象标为final的;

  c.类与DI容器高度耦合,我们不能在外部使用它;

d.类不通过反射不能被实例化(例如单元测试中),你需要用DI容器去实例化它,这更像集成测试;

... etc.

来自Spring官方文档的建议:  
在Spring 3.x 中,Spring团队建议我们使用setter来注入:

大致是说大量的构造器参数会显得非常笨重,尤其是当属性是可选的时候。setter方法可以使类的对象在后来重新配置或者重新注入。提供所有的依赖意味着对象总是返回一个完全初始化状态的client客户端(调用)。缺点是对象变得不那么适合重新配置和重新注入。

而在Spring 4.x 中,Spring团队不再建议我们使用setter来注入,改为了constructor:

Spring团队通常建议使用构造器来注入,因为它允许一个应用程序组件实现为不可变对象,并确保所需的依赖项不是空。此外构造器注入组件总是返回一个完全初始化状态的client客户端(调用)。附注,大量的构造函数参数是一个糟糕的代码习惯,看起来也很坏,这意味着类可能有太多的责任,应该被重构,以更好地解决适当的关注点分离。

setter方法只应该主要的用在可以在类中指定合理的默认值的可选的依赖关系。否则,用到依赖的所有地方都应该进行非空检查。setter注入的一个好处是,setter方法使类的对象可以在之后重新配置或者重新注入。

(以上是本人的渣渣英语翻译结合有道得来。。大佬看到请轻喷)

总结:

1.强制性的依赖性或者当目标不可变时,使用构造函数注入(应该说尽量都使用构造器来注入

2.可选或多变的依赖使用setter注入(建议可以使用构造器结合setter的方式来注入

3.在大多数的情况下避免field域注入(感觉大多数同学可能会有异议,毕竟这个方式写起来非常简便,但是它的弊端确实远大于这些优点

Spring注解依赖注入的三种方式的优缺点以及优先选择的更多相关文章

  1. ASP.NET MVC中使用Unity进行依赖注入的三种方式

    在ASP.NET MVC中使用Unity进行依赖注入的三种方式 2013-12-15 21:07 by 小白哥哥, 146 阅读, 0 评论, 收藏, 编辑 在ASP.NET MVC4中,为了在解开C ...

  2. Spring IOC 依赖注入的两种方式XML和注解

    依赖注入的原理 依赖注入的方式---XML配置 依赖注入的方式---注解的方式 Spring 它的核心就是IOC和AOP.而IOC中实现Bean注入的实现方式之一就是DI(依赖注入). 一 DI的原理 ...

  3. SSH深度历险记(八) 剖析SSH核心原则+Spring依赖注入的三种方式

           于java发育.一类程序猿必须依靠类的其他方法,它是通常new依赖类的方法,然后调用类的实例,这样的发展问题new良好的班统一管理的例子.spring提出了依赖注入的思想,即依赖类不由程 ...

  4. SSH深度历险(八) 剖析SSH核心原理+Spring依赖注入的三种方式

           在java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依 ...

  5. Spring中依赖注入的四种方式

    在Spring容器中为一个bean配置依赖注入有三种方式: · 使用属性的setter方法注入  这是最常用的方式: · 使用构造器注入: · 使用Filed注入(用于注解方式). 使用属性的sett ...

  6. Spring依赖注入的三种方式

    看过几篇关于Spring依赖注入的文章,自己简单总结了一下,大概有三种方式: 1.自动装配 通过配置applicationContext.xml中的标签的default-autowire属性,或者标签 ...

  7. Spring基础05——Spring依赖注入的三种方式

    Spring支持3种依赖注入的方式:属性注入.构造器注入.工厂 1.属性注入 属性注入即通过setter方法注入Bean的属性或依赖的对象.使用<property>元素,使用name属性指 ...

  8. spring——依赖注入的三种方式

    1 构造器注入(与构造器有直接关系) 默认无参构造 3种构造方式:通过<contructor-arg>调用类中的构造器 下标 <bean id="userService&q ...

  9. spring4之依赖注入的三种方式

    1.Setter注入 <bean id="helloWorld" class="com.jdw.spring.beans.HelloWorld"> ...

随机推荐

  1. 重温javascript数据类型

    在javaScript中,有五种简单的数据类型,分别是 Undefined Null Boolean Number String 还有一种复杂的数据类型object,object本质是有一组无序的名值 ...

  2. Siamese Network理解

    提起siamese network一般都会引用这两篇文章: <Learning a similarity metric discriminatively, with application to ...

  3. 开发中关于Git那些事(续:Git变基)

    其实上一篇写的内容仅仅是Git的冰山一角,如果你认为Git就是简简单单的几行命令,那只能说明你还没有真正了解Git这个强大的内容寻址文件系统.这篇文章,还是接着介绍一些实用但是很少有人知晓的一些命令, ...

  4. SqlServer Lock_Escalation

    在今天的文章里,我想谈下SQL Server里锁升级(Lock Escalations).锁升级是SQL Server使用的优化技术,用来控制在SQL Server锁管理里把持锁的数量.我们首先用SQ ...

  5. 转载:DNS解析过程详解

    2015-09-20 此好文是转载,如有侵权联系我,立马删掉 DNS的几个基本概念: 一. 根域 就是所谓的“.”,其实我们的网址www.baidu.com在配置当中应该是www.baidu.com. ...

  6. 6.前端基于react,后端基于.net core2.0的开发之路(6) 服务端渲染(SSR)

    0.源码地址 https://gitee.com/teambp/ScaffoldClient  这个地址下载对应源码. 1.服务端渲染是啥? 就是在服务器进行页面渲染(废话),当页面展示后,显示的就是 ...

  7. chrome调试工具高级不完整使用指南(实战一)

    三.chrome调试工具实战 3.1 获取界面对应的HTML和修改样式 我们以博客园为例子来分析. 通过上面的操作就可以定位到对应的HTML代码 左侧菜单显示的就是当前指定元素层叠样式的一个情况 上面 ...

  8. 【01背包】洛谷P1282多米诺骨牌

    题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中,S1=6+1+1+1=9, ...

  9. 自己写的驱动用CreateFile打开时错误码返回1的问题

    就像题目上说的,今天在写一个例子代码时遇到了这个问题,下面是当时驱动层和应用层的代码: #include <ntddk.h> #define BASE_CODE 0x800 #define ...

  10. 【读书笔记】【深入理解ES6】#12-代理(Proxy)和反射(Reflection)API

    代理(Proxy)是一种可以拦截并改变底层JavaScript引擎操作的包装器,在新语言中通过它暴露内部运作的对象,从而让开发者可以创建内建的对象. 数组问题 在ECMAScript6出现之前,开发者 ...