对于Spring的初学者来说,在一开始接触Spring的依赖注入和控制反转的时候很容易产生概念上的混淆,笔者也经常把这两者弄混。下面我们通过简单的语言来描述这两个概念。
控制反转(IoC)
当某个java对象(调用者)需要调用另一个java对象(被调用者,即被依赖对象)时,在传统模式下,调用者通常会采用"new 被调用者"的代码方式来创建对象,这种方式会导致调用者与被调用者之间的耦合性增加,不利于后期项目的升级和维护。
在使用Spring框架之后,对象的实例不再由调用者来创建,而是由Spring容器来创建,Spring容器会负责控制程序之间的关系,而不是由调用者的程序代码直接控制。这样,控制权由应用代码转移到了Spring容器,控制权发生了反转,这就是Spring的控制反转。
依赖注入(Dependency Injection)
从Spring容器的角度来看,Spring容器负责将被依赖对象赋值给调用者的成员变量,这相当于为调用者注入了它依赖的实例,这就是Spring的依赖注入。
实例解释
这里列举我在另一篇作者的博客中看到的例子,讲解的非常好。
不管是依赖注入,还是控制反转,都说明Spring采用动态、灵活的方式来管理各种对象。对象与对象之间的具体实现互相透明。在理解依赖注入之前,看如下这个问题在各种社会形态里如何解决:一个人(Java实例,调用者)需要一把斧子(Java实例,被调用者)。
(1) 原始社会里,几乎没有社会分工。需要斧子的人(调用者)只能自己去磨一把斧子(被调用者)。对应的情形为:Java程序里的调用者自己创建被调用者。
这种情况下,Java实例的调用者创建被调用的Java实例,必然要求被调用的Java类出现在调用者的代码里。无法实现二者之间的松耦合。
(2) 进入工业社会,工厂出现。斧子不再由普通人完成,而在工厂里被生产出来,此时需要斧子的人(调用者)找到工厂,购买斧子,无须关心斧子的制造过 程。对应Java程序的简单工厂的设计模式。这种情况下,调用者无须关心被调用者具体实现过程,只需要找到符合某种标准(接口)的实例,即可使用。此时调用的代码面向接口编程,可以让调用者和被调用者解耦,这也是工厂模式大量使用的原因。但调用者需要自己定位工厂,调用者与特定工厂耦合在一起。
(3) 进入“按需分配”社会,需要斧子的人不需要找到工厂,坐在家里发出一个简单指令:需要斧子。斧子就自然出现在他面前。对应Spring的依赖注入。
这种情况下,调用者无须自己定位工厂,程序运行到需要被调用者时,系统自动提供被调用者实例。事实上,调用者和被调用者都处于Spring的管理下,二者之间 的依赖关系由Spring提供。
**出处**:https://blog.csdn.net/jianyuerensheng/article/details/50837171?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160250106219725255556480%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=160250106219725255556480&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v3~pc_rank_v2-2-50837171.first_rank_ecpm_v3_pc_rank_v2&utm_term=spring%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5%E5%92%8C%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC&spm=1018.2118.3001.4187