面试突击73:IoC 和 DI 有什么区别?

6b7edb7d09387f679bd3b5ab4ce06433.jpeg

作者 | 磊哥

来源 | Java面试真题解析(ID:aimianshi666)

转载请联系授权(微信ID:GG_Stone)

IoC 和 DI 都是 Spring 框架中的重要概念,就像玫瑰花与爱情一样,IoC 和 DI 通常情况下也是成对出现的。那 IoC 和 DI 什么关系和区别呢?接下来,我们一起来看。

1.IoC 介绍

IoC 是 Inversion of Control 的缩写,翻译成中文是“控制反转”的意思,它不是一个具体的技术,而是一个实现对象解耦的思想。

要解释什么是解耦?就要了解什么是耦合,所谓的耦合是指:两个或两个以上对象存在依赖,当一方修改之后会影响另一方,那么就说这些对象间存在耦合。而解耦就是解除两个或两个以上对象,修改之后影响另一方的问题。

那 IoC(控制反转)是如何实现解耦的呢?

我们来举一个例子,比如 A 对象中需要使用 B 对象的某个方法,那么我们通常的实现方法是这样的:

class A {public void init() {// 调用 B 类中的 init 方法B b = new B();b.init();}
}
class B {public B() {}public void init() {System.out.println("你好,世界。");}
}

然而此时对象 A 和对象 B 是存在耦合的,因为一旦修改了 B 对象构造方法的参数之后,那么 A 对象里面的写法也要跟着改变,比如当我们将构造方法改为以下代码时:

class B {public B(String name) {System.out.println("姓名:" + name);}public void init() {System.out.println("你好,世界。");}
}

此时构造方法已经从原本无参构造方法变成了有参的构造方法,这里不考虑构造方法重载的情况,因为实际业务中,很可能是 B 类的构造方法写错了,忘记加参数了,于是后面又补充了一个参数,此时是不需要对构造方法进行重载的,那么此时,之前对象 A 里面的调用就会报错,如下图所示:3744240d8a67be1e992629d4e323c0c4.png这就是开发中经常遇到的一个问题,那怎么解决呢?

我们可以通过将对象传递而并 new 对象的方式来解决,如下代码所示:

class A {// 先定义一个需要依赖的 B 对象private B b;// 通过构造方法实现赋值(初始化)public A(B b) {this.b = b;}public void init() {// 调用 B 类中的 init 方法b.init();}
}
class B {public B(String name) {System.out.println("姓名:" + name);}public void init() {System.out.println("你好,世界。");}
}

这样改造之后,无论构造方法怎么修改,即使需要加更多的参数,而调用它的 A 类都无需做任何修改,这样就实现了对象的解耦。

那这个解耦的示例和 IoC 有什么关系呢?

IoC 实现的思路和上述示例一样,就是通过将对象交给 Spring 中 IoC 容器管理,在其他类中不直接 new 对象,而是通过将对象传递到当前类的方式来实现解耦的。

小结

在 new 对象的时代,对象的管理权是由当前类控制的,而有了 IoC 之后,对象的管理权就交给非当前类的 IoC 容器管理了,此时对象的管理权就发生了反转和改变,这就是 IoC,这就是控制(权)反转。

2.DI 介绍

DI 是 Dependency Injection 的缩写,翻译成中文是“依赖注入”的意思。依赖注入不是一种设计实现,而是一种具体的技术,它是在 IoC 容器运行期间,动态地将某个依赖对象注入到当前对象的技术就叫做 DI(依赖注入)

在上述示例中,A 类在使用 B 类时,就是通过构造方法将依赖对象 B 引入的,这种实现方法就可以看作是通过构造方法实现依赖注入的手段,具体代码如下:

class A {// 先定义一个需要依赖的 B 对象private B b;// 通过构造方法实现赋值public A(B b) {this.b = b;}public void init() {// 调用 B 类中的 init 方法b.init();}
}

3.IoC VS DI

从上面的内容中我们可以看出,IoC 和 DI 虽然定义不同,但它们所做的事情都是一样的,都是用来实现对象解耦的,而二者又有所不同:IoC 是一种设计思想,而 DI 是一种具体的实现技术

比如,磊哥今天心情比较好,想出去吃顿好的,那么“想吃顿好的”就是一种思想、就是 IoC。

但什么才是“好的(饭)”呢?海底捞还是韩式料理?具体吃什么是 DI。

因此“磊哥今天心情比较好,想出去吃顿好的”是一种思想、是 IoC,而吃一顿海底捞而非韩式料理就是具体的实现、是 DI。

总结

IoC 和 DI 都是 Spring 框架中的重要概念,它们都是用来实现对象解耦的,其中 IoC(控制反转)是一种设计思想,而 DI(依赖注入)是一种具体的实现手段。

是非审之于己,毁誉听之于人,得失安之于数。

公众号:Java面试真题解析

面试合集:https://gitee.com/mydb/interview

ab2de3fe3e1adc3fb166c72dffb163ff.gif

往期推荐

d99ee6bc9c658435644803ffd017025d.jpeg

面试突击72:输入URL之后会执行什么流程?


c0c57fca6e4df3857b12a0c183906f4d.jpeg

面试突击71:GET 和 POST 有什么区别?


3153778df24da4cc4e0505e7598ac100.jpeg

面试突击70:什么是粘包和半包?怎么解决?


d57e656f7bd8ee05ee2492a6e8a09ad8.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/544010.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MyBatis整合Spring的实现(13)

2019独角兽企业重金招聘Python工程师标准>>> 本章中分析insert元素的解析。 1 配置文件 <insert id"insert" parameterType"cn.vansky.schedule.time.menu.bo.Menu"><!--WARNING - mbggeneratedThis element is automatically generat…

python 生成对称矩阵_对称矩阵| 使用Python的线性代数

python 生成对称矩阵Prerequisites: 先决条件&#xff1a; Defining a matrix 定义矩阵 Identity matrix 身份矩阵 Transpose matrix 转置矩阵 In linear algebra, if the matrix and its transpose are equal, then the matrix is symmetric (MT M). 在线性代数中&#xff0…

麻了,代码改成多线程,竟有9大问题

很多时候&#xff0c;我们为了提升接口的性能&#xff0c;会把之前单线程同步执行的代码&#xff0c;改成多线程异步执行。比如&#xff1a;查询用户信息接口&#xff0c;需要返回用户基本信息、积分信息、成长值信息&#xff0c;而用户、积分和成长值&#xff0c;需要调用不同…

Javascript 事件冒泡处理

js中子节点和父节点有相同的事件,怎么只触发子节点的事件 方法一、在子节点触发事件里加上阻止冒泡$("p").click(function(event){ event.stopPropagation(); // do something }); 原生的类似 只是不同浏览器有些不同方法二、在父节点触发事件里加上阻止冒泡…

PHP rewinddir()函数与示例

PHP rewinddir()函数 (PHP rewinddir() function) rewinddir() function is used to rewind/reset the directory handle which is created by the opendir() function. rewinddir()函数用于后退/重置由opendir()函数创建的目录句柄。 Syntax: 句法&#xff1a; rewinddir(di…

浅聊一下线程池的10个坑

日常开发中&#xff0c;为了更好管理线程资源&#xff0c;减少创建线程和销毁线程的资源损耗&#xff0c;我们会使用线程池来执行一些异步任务。但是线程池使用不当&#xff0c;就可能会引发生产事故。今天跟大家聊聊线程池的10个坑。大家看完肯定会有帮助的~线程池默认使用无界…

Linux命令行上执行操作,不退回命令行的解决方法

问题描述&#xff1a; 如果你现在登录Centos执行了某个操作&#xff0c;但是操作一直占用命令行&#xff0c;命令行显示的也都是这个命令相关的操作&#xff0c;我想做其它事情 &#xff0c;该怎么办呢 &#xff1f; 解决方法&#xff1a; 根据《Linux命令行与Shell编程大全第2…

python 当日日期_Python程序寻找当日赢家

python 当日日期Problem statement: 问题陈述&#xff1a; There are two basketball teams (Team1 and Team2) in a school and they play some matches every day depending on their time and interest. Some days they play 3 matches, some days 2, some days 1, etc. 一…

SpringBoot 读取配置文件的 5 种方法!

作者 | 磊哥来源 | Java面试真题解析&#xff08;ID&#xff1a;aimianshi666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;Spring Boot 中读取配置文件有以下 5 种方法&#xff1a;使用 Value 读取配置文件。使用 ConfigurationProperties 读…

机器学习朴素贝叶斯算法_机器学习中的朴素贝叶斯算法

机器学习朴素贝叶斯算法朴素贝叶斯算法 (Naive Bayes Algorithm) Naive Bayes is basically used for text learning. Using this algorithm we trained machine from text. 朴素贝叶斯基本上用于文本学习。 使用此算法&#xff0c;我们从文本中训练了机器。 Let’s understan…

jQuery的ajaxFileUpload上传文件插件刷新一次才能再次调用触发change

关于用ajaxfileupload时&#xff0c;遇到一个要刷新一次页面才能再次上传&#xff0c;用live()方法来绑定 file表单 的change事件就能够解决&#xff0c;直接$("xxx").change()这样只能调用一次&#xff0c;再次调用change的时候不能触发;IE浏览器下 file表单 选择完…

使用阿里巴巴 Druid 轻松实现加密!

作者 | 磊哥来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;为什么要加密&#xff1f;现在的开发习惯&#xff0c;无论是公司的项目还是个人的项目&#xff0c;都会选择将源码上传到 Gi…

xml不显示css样式_如何使用CSS显示XML?

xml不显示css样式Introduction: 介绍&#xff1a; You must be aware of the term XML and must have dealt with these various XML files while developing a web page or website. This article focuses entirely on XML and how to display them using CSS. There are num…

Spring Boot 如何优雅的校验参数?

今天介绍一下 Spring Boot 如何优雅的整合JSR-303进行参数校验&#xff0c;说到参数校验可能都用过&#xff0c;但网上的教程大多是简单的介绍&#xff0c;所以我们今天详细看来一下 。什么是 JSR-303&#xff1f;JSR-303 是 JAVA EE 6 中的一项子规范&#xff0c;叫做 Bean Va…

ruby hash方法_Ruby中带有示例的Hash.keys方法

ruby hash方法哈希键方法 (Hash.keys Method) In this article, we will study about Hash.keys Method. The working of the method cant be assumed because of its quite a different name. Let us read its definition and understand its implementation with the help of…

c#组元(Tuple)的使用

组元(Tuple)是C# 4.0引入的一个新特性&#xff0c;可以在.NET Framework 4.0或更高版本中使用。组元使用泛型来简化类的定义&#xff0c;多用于方法的返回值。在函数需要返回多个类型的时候&#xff0c;就不必使用out , ref等关键字了&#xff0c;直接定义一个Tuple类型&#x…

浅谈一下 MyBatis 批量插入的 3 种方法!

作者 | 磊哥来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone批量插入功能是我们日常工作中比较常见的业务功能之一&#xff0c;今天咱们来一个 MyBatis 批量插入的汇总篇&#xff0c;同时对 3 种实现…

VMware 11安装Mac OS X 10.10 及安装Mac Vmware Tools.

http://www.bubuko.com/infodetail-790015.html#title3 http://my.oschina.net/vigiles/blog/141689#OSC_h2_9 http://www.360doc.com/content/10/0316/11/750552_18965817.shtml转载于:https://www.cnblogs.com/yuyang2100/p/4938829.html

kotlin 查找id_Kotlin程序查找圆柱体区域

kotlin 查找idA cylinder is a three-dimensional structure which has circular bases parallel to each other. 圆柱是具有彼此平行的圆形底的三维结构。 Formula to find area of a cylinder: 2*PI*(radiusheight) 查找圆柱体面积的公式&#xff1a;2 * PI *(半径高度) Gi…

快速搭建 SpringCloud Alibaba Nacos 配置中心!

作者 | 磊哥来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;Spring Cloud Alibaba 是阿里巴巴提供的一站式微服务开发解决方案&#xff0c;目前已被 Spring Cloud 官方收录。而 Nacos 作…