Spring框架中的控制反转(IoC),本来是一个很简单的概念,但是在网上却常常被人乱解释一通,人云亦云的结果就是混乱和难以理解。
我们先来看一下网上流行的解释是怎么说的:
谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对 象的创建;谁控制谁?当然是IoC 容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。
为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。
以上说法其实只涉及到了IoC的一个应用场景(依赖控制),依赖控制虽然是一种常用场景,但是通过了依赖控制来理解IoC就一定会把Ioc与依赖注入(DI)搞混淆,越描越黑,彻底分不开了。
早在2004年,Martin Fowler大神的一篇博文讨论了IoC,网上很多讨论IoC的文章都提到了Martin Fowler,但是我相信很多人都没有看过原文
https://martinfowler.com/bliki/InversionOfControl.html
我们来看下Martin Fowler是怎么说的:
The control is inverted - it calls me rather me calling the framework.
控制是反向的-它(框架)调用我,而不是我调用框架。
Inversion of Control is a key part of what makes a framework different to a library.
控制反转是使得框架与库不同的关键部分。
A library is essentially a set of functions that you can call, these days usually organized into classes. Each call does some work and returns control to the client.
库本质上是您可以调用的一组函数,这些函数通常组织成类。每个调用都会执行一些工作,并将控制权返回给客户端。
A framework embodies some abstract design, with more behavior built in. In order to use it you need to insert your behavior into various places in the framework either by subclassing or by plugging in your own classes. The framework's code then calls your code at these points.
框架体现了一些抽象设计,并内置了更多行为。要使用它,您需要通过子类化或插入自己的类将行为插入到框架中的不同位置。然后,框架的代码在这些位置调用您的代码。
看明白了吗?一句话:控制反转就是把程序执行过程由原来的程序员控制转向由框架来控制,这就是框架与库(lib)最关键的区别。
所以依赖注入只是IoC的一部分应用场景而已,其实你每次在别人定义的回调函数中写代码都是控制反转。