一, 最开始的理解
1.1.IoC 控制反转
就是我们现在不需要去 new 对象了, 需要的话直接通过 getbean 去获取就行了(主要体现在可配置的文件).
没用之前
用了之后
1.2.DI 依赖注入
就是说我们现在假如一个 bean 依赖另一个 bean, 比如我们案例中的 student 依赖 address, 我们不需要在容器中在去找 student 的依赖 address, 这个时候容器已经帮助我们做好了, 我们直接获取到 student 对象的时候直接 get.addr 就行了. 意思就是说容器已经把所有的依赖梳理好了, 我们既不需要在去 new address 对象, 也不需要考虑依赖它和 student 的依赖关系, 直接用就行了.
二: 后来的理解
阅读源码 + 博文 https://blog.csdn.net/qq_42709262/article/details/81951402.
其实控制反转和依赖注入是一个意思, 但是控制反转起的名称不太好, 没有把动态注入的意思给加进来.
所以用依赖注入这个名称更能表达这种思想.
我们我们这样理解: 依赖注入 = 控制反转 + 动态注入(可能也有错误就不纠结这个名称了, 假如面试的话, 就说两者是一样的, 它的意思就是下面要说的就行了, 把思想说明白就行了)
下面主要说一下它的思想:
2.1, 对象的创建(IoC)
以前我们创建对象的时候(在没有 spring 框架之前), 我们一般都是 new 出来的, 而且还得考虑对象的销毁等等, 这个就会有几个问题.
问题一: 每个对象我们都需要去 new 一遍, 而且假如在企业中, 我们有几十个上百个类中间有依赖关系, 那还不把人搞死.
问题二: 内存泄漏, 有些全局变量, 我们 java 代码程序员, 一般都不考虑它的销毁的, 假如一个特殊的类不用了一直存在的话很容易造成内存泄漏的.
spring 的思想就是把所有对象的创建和销毁都交给他来做.
这样我们就可以需要对象都向 IoC 容器要就行了. 对于 spring 框架来说, 就是由 spring 来负责控制对象的生命周期和对象间的关系.
那么 IoC 是如何做的呢? 有点像通过婚介找女朋友, 在我和女朋友之间引入了一个第三者: 婚姻介绍所. 婚介管理了很多男男女女的资料, 我可以向婚介提出一个列表, 告诉它我想找个什么样的女朋友, 比如长得像李嘉欣, 身材像林熙雷, 唱歌像周杰伦, 速度像卡洛斯, 技术像齐达内之类的, 然后婚介就会按照我们的要求, 提供一个 mm, 我们只需要去和她谈恋爱, 结婚就行了. 简单明了, 如果婚介给我们的人选不符合要求, 我们就会抛出异常. 整个过程不再由我自己控制, 而是有婚介这样一个类似容器的机构来控制.
所有的类都会在 spring 容器中登记, 告诉 spring 你是个什么东西, 你需要什么东西, 然后 spring 会在系统运行到适当的时候, 把你要的东西主动给你, 同时也把你交给其他需要你的东西. 所有的类的创建, 销毁都由 spring 来控制, 也就是说控制对象生存周期的不再是引用它的对象, 而是 spring. 对于某个具体的对象而言, 以前是它控制其他对象, 现在是所有对象都被 spring 控制, 所以这叫控制反转.
2.2,DI(依赖注入)
IoC 的一个重点是在系统运行中, 动态的向某个对象提供它所需要的其他对象. 这一点是通过 DI(Dependency Injection, 依赖注入)来实现的.
比如对象 A 需要操作数据库, 以前我们总是要在 A 中自己编写代码来获得一个 Connection 对象, 有了 spring 我们就只需要告诉 spring,A 中需要一个 Connection, 至于这个 Connection 怎么构造, 何时构造, A 不需要知道. 在系统运行时, spring 会在适当的时候制造一个 Connection, 然后像打针一样, 注射到 A 当中, 这样就完成了对各个对象之间关系的控制. A 需要依赖 Connection 才能正常运行, 而这个 Connection 是由 spring 注入到 A 中的, 依赖注入的名字就这么来的. 那么 DI 是如何实现的呢? Java 1.3 之后一个重要特征是反射(reflection), 它允许程序在运行的时候动态的生成对象, 执行对象的方法, 改变对象的属性, spring 就是通过反射来实现注入的.
在比如我们阅读源码的时候当我们加载 xml 配置的时候 = IoC 容器的初始化 = 项目启动时运行: 我们主要做了定位 (资源配置 import,url,classpath), 加载(解析配置文件把 bean 包装成 beanDedefine 对象), 注册(把已经初始化的 beanDedefine 对象放入到 IoC 容器中) 之后相当于把 xml 的配置, 通过 xml 自己方式的解析转换成 spring 自己的解析方式.
当我们在运行程序的时候 = xml 的依赖注入 = 项目加载时运行, 我们主要做了把在 IoC 容器中的 beanDedefine 对象 (spring 自己的解析方式) 转换成了我们自己的对象 (比如说是 user 实体类, 相当于创建了 user 的实体类), 然后给对象(我们自己写的实体类) 赋值. DI 更大程度上是在这里提现的, 就是动态的给创建了对象, 并且给对象赋予了值.
三: 再后来的理解
后续补充
来源: http://www.bubuko.com/infodetail-2973065.html