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

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. Struts2-整理笔记(四)Action生命周期、如何获取参数(3种)、集合类型参数封装

    一.Action生命周期 每次请求到来时,都会创建一个新的Action实例 Action是线程安全的,可以使用成员变量接收参数 二.获取参数的方式(3种) 1.属性驱动获得参数 每次请求Action时 ...

  2. JavaScript的DOM编程--10--删除节点

    1). removeChild(): 从一个给定元素里删除一个子节点 var reference = element.removeChild(node); 返回值是一个指向已被删除的子节点的引用指针. ...

  3. Adb+.net 实现微信跳一跳自动化

    第一次用adb,一开始只是想试试看能不能解析出,没有看网上的现有解析方式. 需要安卓机开启usb 调试+电脑运行.打开跳一跳的界面 点击程序 [开始]按钮即可开始,别的按钮都是调试用的 主要流程是用a ...

  4. 使用nginx 的反向代理 给 kibana加上basic的身份认证

    第一步准备工作 准备用户名密码: 更改host文件 第二步,安装nginx ubuntu安装Nginx之后的文件结构大致为:所有的配置文件都在/etc/nginx下,并且每个虚拟主机已经安排在了/et ...

  5. jQuery 遍历函数(八)

    函数 描述 .add() 将元素添加到匹配元素的集合中. .andSelf() 把堆栈中之前的元素集添加到当前集合中. .children() 获得匹配元素集合中每个元素的所有子元素. .closes ...

  6. 对比Tornado和Twisted两种异步Python框架

    做Python的人,一定知道两个性能优秀的异步网络框架:tornado,和twisted. 那么,这两个著名的框架,又有什么异同呢?tornado和twisted,我都用在几个游戏项目中,做过后端,觉 ...

  7. Hadoop2.9.0安装

    参考 https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/SingleCluster.html 1.下载并解 ...

  8. Hadoop 新生报道(四) WordCount

         WordCount是hadoop里hello word级的第一个程序,作为一个萌新,我也来跑一跑这个,附带针对新人的说明.      所谓WordCount,就是统计一个或几个文档中相同的单 ...

  9. SQLAlchemy基础操作二

    多线程示例 import time import threading from sqlalchemy.ext.declarative import declarative_base from sqla ...

  10. Vue2.0 相对于Vue1.0的变化:生命周期

    1.生命周期 根据提供的生命周期钩子说明Vue.js实例各个阶段的情况,Vue.js 2.0对不少钩子进行了修改,以下说明:(灰色字体代表是 2.0已经废弃或者被更名的钩子,黑色字体代表1.0 和2. ...