一、前言

​ Spring框架对Java开发的重要性不言而喻,其核心特性就是IOC(Inversion of Control, 控制反转)和AOP,平时使用最多的就是其中的IOC,我们通过将组件交由Spring的IOC容器管理,将对象的依赖关系由Spring控制,避免硬编码所造成的过度程序耦合。前几天的时候,笔者的同事问我为什么要使用构造器的注入方式,我回答说因为Spring文档推荐这种,而说不出为什么 T^T,后面抽时间了解了一下,下面就是笔者要讨论的就是其注入方式。


二、常见的三种注入方式

​ 笔者为了方便起见就只是用注解的方式注入(现在也很少使用xml了吧,(~ ̄▽ ̄)~)

2.1 field注入

@Controller
public class FooController {
@Autowired
//@Inject
private FooService fooService; //简单的使用例子,下同
public List<Foo> listFoo() {
return fooService.list();
}
}

这种注入方式应该是笔者目前为止开发中见到的最常见的注入方式。原因很简单:

  1. 注入方式非常简单:加入要注入的字段,附上@Autowired,即可完成。
  2. 使得整体代码简洁明了,看起来美观大方。


2.2 构造器注入

@Controller
public class FooController { private final FooService fooService; @Autowired
public FooController(FooService fooService) {
this.fooService = fooService;
} //使用方式上同,略
}

​ 在Spring4.x版本中推荐的注入方式就是这种,相较于上面的field注入方式而言,就显得有点难看,特别是当注入的依赖很多(5个以上)的时候,就会明显的发现代码显得很臃肿。对于从field注入转过来+有强迫症的园友 来说,简直可以说是石乐志  (`Д´*)9。对于这一点我们后面再来讨论,别急。


2.3 setter注入

@Controller
public class FooController { private FooService fooService; //使用方式上同,略
@Autowired
public void setFooService(FooService fooService) {
this.fooService = fooService;
}
}

​ 在Spring3.x刚推出的时候,推荐使用注入的就是这种,笔者现在也基本没看到过这种注解方式,写起来麻烦,当初推荐Spring自然也有他的道理,这里我们引用一下Spring当时的原话:

The Spring team generally advocates setter injection, because large numbers of constructor arguments can get unwieldy, especially when properties are optional. Setter methods also make objects of that class amenable to reconfiguration or re-injection later. Management through JMX MBeans is a compelling use case.

Some purists favor constructor-based injection. Supplying all object dependencies means that the object is always returned to client (calling) code in a totally initialized state. The disadvantage is that the object becomes less amenable to reconfiguration and re-injection.

​ 咳咳,简单的翻译一下就是:构造器注入参数太多了,显得很笨重,另外setter的方式能用让类在之后重新配置或者重新注入


​ 那么后面为什么又换成构造器注入了呢?(喂喂喂,Spring你前一大版本还贬低构造器注入,后面就立刻捧人家了不好吧,不过能用于承认自己的错误,才是真正令人称赞的地方吧 (๑•̀ㅂ•́)و✧)


三、构造器注入的好处

​ 先来看看Spring在文档里怎么说:

The Spring team generally advocates constructor injection as it enables one to implement application components as immutable objects and to ensure that required dependencies are not null. Furthermore constructor-injected components are always returned to client (calling) code in a fully initialized state.

​ 咳咳,再来简单的翻译一下:这个构造器注入的方式啊,能够保证注入的组件不可变,并且确保需要的依赖不为空。此外,构造器注入的依赖总是能够在返回客户端(组件)代码的时候保证完全初始化的状态


下面来简单的解释一下:

  • 依赖不可变:其实说的就是final关键字,这里不再多解释了。不明白的园友可以回去看看Java语法。
  • 依赖不为空(省去了我们对其检查):当要实例化FooController的时候,由于自己实现了有参数的构造函数,所以不会调用默认构造函数,那么就需要Spring容器传入所需要的参数,所以就两种情况:1、有该类型的参数->传入,OK 。2:无该类型的参数->报错。所以保证不会为空,Spring总不至于传一个null进去吧

    【Spring】浅谈spring推荐构造器注入的更多相关文章

    1. spring 依赖注入总结--为什么官方推荐构造器注入

      一 公司小伙伴使用了构造器注入,说是spring的官方推荐.但是,我问了三个问题,他都答不出来,感觉能写篇博文. 官方为什么推荐构造器注入? 构造器注入和属性注入的区别是啥? 你知道有几种注入方式吗? ...

    2. 浅谈Spring的两种配置容器

      浅谈Spring的两种配置容器 原文:https://www.jb51.net/article/126295.htm 更新时间:2017年10月20日 08:44:41   作者:黄小鱼ZZZ     ...

    3. 浅谈Spring中的Quartz配置

      浅谈Spring中的Quartz配置 2009-06-26 14:04 樊凯 博客园 字号:T | T Quartz是一个强大的企业级任务调度框架,Spring中继承并简化了Quartz,下面就看看在 ...

    4. 浅谈.NET编译时注入(C#-->IL)

      原文:浅谈.NET编译时注入(C#-->IL) .NET是一门多语言平台,这是我们所众所周知的,其实现原理在于因为了MSIL(微软中间语言)的一种代码指令平台.所以.NET语言的编译就分为了两部 ...

    5. 浅谈spring为什么推荐使用构造器注入

      转载自: https://www.cnblogs.com/joemsu/p/7688307.html 一.前言 ​ Spring框架对Java开发的重要性不言而喻,其核心特性就是IOC(Inversi ...

    6. 【Spring】浅谈spring为什么推荐使用构造器注入

      一.前言 ​ Spring框架对Java开发的重要性不言而喻,其核心特性就是IOC(Inversion of Control, 控制反转)和AOP,平时使用最多的就是其中的IOC,我们通过将组件交由S ...

    7. 浅谈spring依赖注入

      了解依赖注入 前言 先了解下控制反转--转自知乎的国哥 如果一个类A 的功能实现需要借助于类B,那么就称类B是类A的依赖,如果在类A的内部去实例化类B,那么两者之间会出现较高的耦合,一旦类B出现了问题 ...

    8. 1.1浅谈Spring(一个叫春的框架)

      如今各种Spring框架甚嚣尘上,但是终归还是属于spring的东西.所以在这里,个人谈一谈对spring的认识,笔者觉得掌握spring原理以及spring所涉及到的设计模式对我们具有极大的帮助.我 ...

    9. 浅谈Spring解决循环依赖的三种方式

      引言:循环依赖就是N个类中循环嵌套引用,如果在日常开发中我们用new 对象的方式发生这种循环依赖的话程序会在运行时一直循环调用,直至内存溢出报错.下面说一下Spring是如果解决循环依赖的. 第一种: ...

    随机推荐

    1. Js函数初学者练习(一)switch-case结构实现计算器。

        前  言 JRedu 给大家介绍一点JS函数的练习题希望初学者多做一些练习能够更好的掌握JS的函数,以及能够提升大家的逻辑思维.(我也是个渣渣希望路过的大神多提建议或意见) 希望能够对大家有所帮助 ...

    2. 【1414软工助教】团队作业8——第二次项目冲刺(Beta阶段) 得分榜

      题目 团队作业8--第二次项目冲刺(Beta阶段) 往期成绩 个人作业1:四则运算控制台 结对项目1:GUI 个人作业2:案例分析 结对项目2:单元测试 团队作业1:团队展示 团队作业2:需求分析&a ...

    3. ERROR: JDWP Unable to get JNI 1.2 environment, jvm->GetEnv() return code = -2

      java编程时偶尔出现运行结果下面这样的错误: ERROR: JDWP Unable to get JNI 1.2 environment, jvm->GetEnv() return code ...

    4. 201521123057 《Java程序设计》 第8周学习总结

      1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容 2. 书面作业 1.List中指定元素的删除(题目4-1) 1.1 实验总结 答:remove中注意应该使用eq ...

    5. 工厂模式 and 单例模式

      工厂模式:使用工厂类使创建类与使用类分离,从而提高代码的易维护性,可扩展性等 工厂模式分位简单工厂模式和工厂方法模式 使用简单工厂模式的步骤:     1.创建父类及其子类         父类中有[ ...

    6. smtp模块使用

      import smtplib from email.mime.text import MIMEText from bs4 import BeautifulSoup from urllib.reques ...

    7. centos 7(Linux) 下yum安装mysql

      1:查询centos7 中是否有可安装的mysql.命令查询 yum list mysql* 没有可安装的mysql软件... 2:sudo rpm -Uvh http://dev.mysql.com ...

    8. Struts框架2

      1.框架:是一个半成品,可以在其基础上在次开发. 2.struts2框架:它是一个web层使用的mvc框架. 3.struts2核心 1.struts2核心 2.xwork核心 4.struts2入门 ...

    9. 翻译:MariaDB wait/nowait

      本文为mariadb官方手册:wait/nowait的译文.原文:https://mariadb.com/kb/en/library/wait-and-nowait/ 从MariaDB 10.3.0开 ...

    10. HTML5可预览多图片ajax上传(使用formData传递数据)

      HTML5可预览多图片ajax上传(使用formData传递数据) 在介绍上传图片之前,我们简单的来了解下FormData的基本使用:介绍完成后这些基本知识后,我们会在文章最后提供一个demo,就是a ...