名词解释
IoC:Inversion of Control(控制反转)
DI:Dependency Injection(依赖注入)
IoC(控制反转)
在学习SSH的时候,对Spring只是有个很基础很基础的了解,只知道照着老师的代码打,不知道原理,想问老师却不知道怎么问。 当时见过这个词,Ioc,很多文章都这么写,
Ioc,c是小写,在我印象中英语的简写规则是每个句子的首单词的首字母要大写(除了介词),于是我就以为Ioc是一个单词的简写,只是瞎猜,也没有Google。后来从头学spring的时候我才知道,是
IoC,C是大写,说明是三个单词的缩写。。。这说明什么问题?说明没事多百度Google,不要瞎猜。
IoC是控制反转的意思,把词拆开来理解
控制
传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象; 比如用户类 Class User 内部依赖于对象用户信息类 Class UserInfo。创建步骤就是:
1、创建用户类 Class User; 2、创建用户信息类 Class UserInfo; 3、将用户信息类主动注入到用户类;
这时候User类对UserInfo类就有了主动控制权。
反转
如果这时候需要再创建一个用户,那么就需要重复执行上面的步骤,很麻烦,于是Spring搞了一个容器,将刚才创建用户的对象放在里面,于是要创建一个新的用户类,就变成了:
1、直接从这个容器里获取用户类 User; 2、容器创建用户类 Class User; 3、容器看用户类是否有依赖对象需要注入,到用户信息类需要注入; 4、容器创建用户信息类 Class UserInfo; 5、容器将用户信息类主动注入到用户类; 6、由容器管理这个对象的生命周期;
看看有了容器以后有什么变化?我们只需要做第一步,后面全都是容器负责。最重要的是字体加粗的第三步。
由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转过来了,对象不再是主动去注入依赖。控制的权限也变成了:容器控制对象。
综上,控制反转不是什么技术,而是一种设计思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是 松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。
DI(依赖注入)
上面的IoC已经说过,核心就是由容器帮我们查找及注入依赖对象,那“依赖注入”不就是这个意思吗?
对!
相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。
所以 IoC 和 DI 是同一个概念的不同角度的描述。
为什么会有两种叫法呢?
1996年,Michael Mattson在一篇有关探讨面向对象框架的文章中,首先提出了 IoC 这个概念。 2004年,Martin Fowler探讨了同一个问题,既然IoC是控制反转,那么到底是“哪些方面的控制被反转了呢?”,经过详细地分析和论证后,他得出了答案:“获得依赖对象的过程被反转了”。 控制被反转之后,获得依赖对象的过程由自身管理变为了由IOC容器主动注入。于是,他给“控制反转”取了一个更合适的名字叫做“依赖注入(Dependency Injection)”。
In the Java community there's been a rush of lightweight containers that help to assemble components from different projects into a cohesive application. Underlying these containers is a common pattern to how they perform the wiring, a concept they refer under the very generic name of "Inversion of Control". In this article I dig into how this pattern works, under the more specific name of "Dependency Injection", and contrast it with the Service Locator alternative. The choice between them is less important than the principle of separating configuration from use.
Martin Fowler这篇文章的原文地址:https://www.martinfowler.com/articles/injection.html
他的这个答案,实际上给出了实现IoC的方法:注入。所谓依赖注入,就是由IoC容器在运行期间,动态地将某种依赖关系注入到对象之中。
这个依赖注入的关系也需要搞清楚:
谁依赖于谁: 应用程序依赖于IoC容器;
为什么需要依赖: 应用程序需要IoC容器来提供对象需要的外部资源(包括对象、资源、常量数据);
谁注入谁: IoC容器注入应用程序某个对象,应用程序依赖的对象;
注入了什么: 某个对象所需要的外部资源(包括对象、资源、常量数据)。
使用IoC框架应该注意什么
使用IoC框架产品能够给我们的开发过程带来很大的好处,但是也要充分认识引入IoC框架的缺点,做到心中有数,杜绝滥用框架。
1、软件系统中由于引入了第三方IoC容器,生成对象的步骤变得有些复杂,本来是两者之间的事情,又凭空多出一道手续,所以,我们在刚开始使用IoC框架的时候,会感觉系统变得不太直观。所以,引入了一个全新的框架,就会增加团队成员学习和认识的培训成本,并且在以后的运行维护中,还得让新加入者具备同样的知识体系。
2、由于IoC容器生成对象是通过反射方式,在运行效率上有一定的损耗。如果你要追求运行效率的话,就必须对此进行权衡。
3、具体到IoC框架产品(比如:Spring)来讲,需要进行大量的配制工作,比较繁琐,对于一些小的项目而言,客观上也可能加大一些工作成本。
4、IoC框架产品本身的成熟度需要进行评估,如果引入一个不成熟的IoC框架产品,那么会影响到整个项目,所以这也是一个隐性的风险。
参考 http://sishuok.com/forum/blogPost/list/2427.htmlhttps://blog.csdn.net/ivan820819/article/details/79744797https://www.martinfowler.com/articles/injection.htmlhttp://www.cnblogs.com/xingyukun/archive/2007/10/20/931331.html