什么是IOC
IOC--Inversion of Control,即“控制反转”,这是一种设计理念,角度比较宏观。在Java开发中,IOC意味着将设计好的对象交给容器控制,而非传统的在Java对象内部直接控制。对于Spring框架来说,就是由spring来负责控制对象的生命周期和对象间的依赖关系。
我们需要理清涉及到的主客体之间的关系
谁控制谁?
传统Java开发中,直接在对象内部通过new进行创建对象,是程序主动去创建所依赖的对象;在IOC中,是由容器来控制对象的创建。
控制什么?
IOC容器主要控制了外部资源获取(java对象,常量数据等)。
什么是反转?
传统Java程序中,是由程序员在对象中通过new去直接获取依赖对象,即正转;由容器负责查找及注入依赖对象,对象只是被动的接受所依赖的对象,所以是反转。
哪个地方反转了?
依赖对象的获取反转了。
IOC能做什么
IOC能帮我们设计出松耦合、更优良的程序。传统java程序都是在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;而有了IOC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,对象与对象之间是松散耦合,方便测试,更重要的是使得程序的整个体系结构变得非常灵活。
举个例子
假设我们需要租一个房子。过去,我们需要到处去找哪里有房源,然后在和房东联系,这个过程是复杂和麻烦的。
传统的程序开发也是如此,我们必须自己设计和面对每个环节。比如,在一个对象中,如果要使用其他对象,就必须手动new一个,使用完之后还要将对象销毁(比如Connection等),对象始终会和其他的接口或类耦合起来。
IOC是干什么的呢?其实就是在我们和房东之间引入的第三者--中介。中介有很多房屋的资料,我可以向中介提要求,告诉他,我想找个什么样的房子,然后中介就会按照我们的要求,提供一处或几处房源。剩下的,我们只需要打钱就行了,简单明了。如果中介给我们的房子不符合要求,我们就会抛出异常。
整个过程不再由我们控制,而是由中介这样一个机构作为容器来控制。Spring的开发方式就是如此,所有的类都会在spring容器中登记,告诉spring这是个什么东西,需要什么依赖,然后spring会在适当的时候,把它要的依赖主动注入,同时也把这个类交给其他需要这个依赖的类。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制。
依赖注入是什么
在Spring的官方文档中有着这么一段话介绍DI
IoC is also known as dependency injection (DI). It is a process whereby objects define their dependencies (that is, the other objects they work with)only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. he container then injects those dependencies when it creates the bean.
大致是说DI是一个过程,对象通过一些方式设置对象的属性来确定对象间的依赖关系,然后,容器在创建Bean时注入这些依赖关系。
仍用租房举例:
我们再详细地讲述一下什么是DI。
DI是具体的技术实现,角度比较微观。这就要求组件之间依赖关系由容器在运行期决定,由容器动态的将某个依赖关系注入到组件之中。而通过依赖注入,我们只需要通过简单的配置,无需任何代码就可指定目标需要的资源,完成业务逻辑,不必关心具体的资源来自何处,由谁实现。
DI是如何实现的呢?
DI在Spring中是通过反射机制实现的,它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性
IOC和DI是什么关系呢?
IOC是在系统运行时,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。IOC和DI是同一思想下不同维度的表现,即是以“依赖注入”的方式实现了“控制反转"的效果。
IOC的优缺点
优点:
- 灵活性好,添加拦截器很容易,而且只需在一个地方完成(如在操作数据库的dao层添加拦截器)
- 可读性高,代码更简短
- 便于测试,进而使代码的质量更高,耦合度更低 缺点:
- 效率有损耗,IOC容器生成对象是通过反射方式实现的
- 配置繁琐,生成对象的步骤变得有些复杂,增加了学习和项目投入运行后的维护成本