一、产生的原因
在采用面向对象方法设计的软件系统中,底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑。即软件系统中对象之间的耦合,对象A和对象B之间有关联,对象B又和对象C有依赖关系,这样对象和对象之间有着复杂的依赖关系,所以才有了控制反转这个设计思想
二、什么是控制反转?
- IoC是Inversion of Control的缩写,有的翻译成“控制反转”,还有翻译成为“控制反向”或者“控制倒置”
- 1996年,Michael Mattson在一篇有关探讨面向对象框架的文章中,首先提出了IoC 这个概念。简单来说就是把复杂系统分解成相互合作的对象,这些对象类通过封装以后,内部实现对外部是透明的,从而降低了解决问题的复杂度,而且可以灵活地被重用和扩展。IoC理论提出的观点大体是这样的:借助于“第三方”实现具有依赖关系的对象之间的解耦
- 所谓控制反转就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的。 这样控制权就由应用转移到了外部容器,控制权的转移就是所谓反转
三、什么是依赖注入(DI)?
1、概念
- IoC的别名,2004年,Martin Fowler(马丁·福勒)探讨了一个问题,既然IoC是控制反转,那么到底是“哪些方面的控制被反转了呢?”,经过详细地分析和论证后,他得出了答案:“获得依赖对象的过程被反转了”。控制被反转之后,获得依赖对象的过程由自身管理对象变为由IoC容器主动注入。于是,他给“控制反转”取了一个更合适的名字叫做“依赖注入(Dependency Injection,DI)”。他的这个答案,实际上给出了实现IoC的方法:注入。
- 所谓依赖注入,就是由IoC容器在运行期间,动态地将某种依赖关系注入到对象之中。
- 所以,依赖注入(DI)和控制反转(IoC)是从不同的角度描述的同一件事情,就是指通过引入IoC容器,利用依赖关系注入的方式,实现对象之间的解耦
2、依赖关系的四种情况
- 说明
对象之间最弱的一种关联方式,是临时性的关联。代码中一般指由局部变量、函数参数、返回值建立的对于其他对象的调用关系 - 四种情况
- ClassA中某个方法的参数类型是ClassB; 这种情况成为耦合;
- ClassA中某个方法的参数类型是ClassB的一个属性; 这种情况成为紧耦合;
- ClassA中某个方法的实现实例化ClassB;
- ClassA中某个方法的返回值的类型是ClassB;
- 如果出现了上述四种情况之一,两个类很有可能就是“依赖”关系。 依赖关系(Dependency):是类与类之间的连接,依赖总是单向的。依赖关系代表一个类依赖于另一个类的定义
3、总结
(Dependency Injection)和控制反转(Inversion of Control)是同一个概念。具体含义是:当某个角色(可能是一个Java实例,调用者)需要另一个角色(另一个Java实例,被调用者)的协助时,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在Spring里,创建被调用者的工作不再由调用者来完成,因此称为控制反转;创建被调用者 实例的工作通常由Spring容器来完成,然后注入调用者,因此也称为依赖注入
四、使用IoC的好处
- 可维护性比较好,非常便于进行单元测试,便于调试程序和诊断故障。代码中的每一个Class都可以单独测试,彼此之间互不影响,只要保证自身的功能无误即可,这就是组件之间低耦合或者无耦合带来的好处。
- 降低对象之间的耦合,每个开发团队的成员都只需要关注自己要实现的业务逻辑,完全不用去关心其他人的工作进展,因为你的任务跟别人没有任何关系,你的任务可以单独测试,你的任务也不用依赖于别人的组件,再也不用扯不清责任了。所以,在一个大中型项目中,团队成员分工明确、责任明晰,很容易将一个大的任务划分为细小的任务,开发效率和产品质量必将得到大幅度的提高。
- 可复用性好,我们可以把具有普遍性的常用组件独立出来,反复应用到项目中的其它部分,或者是其它项目,当然这也是面向对象的基本特征。显然,IoC更好地贯彻了这个原则,提高了模块的可复用性。符合接口标准的实现,都可以插接到支持此标准的模块中。
- IoC生成对象的方式转为外置方式,也就是把对象生成放在配置文件里进行定义,这样,当我们更换一个实现子类将会变得很简单,只要修改配置文件就可以了,完全具有热插拨的特性
五、IoC的原理
控制反转是Spring框架的核心。其原理是基于面向对象(OO)设计原则的The Hollywood Principle(好莱坞法则):Don't call us, we'll call you(别找我,我会来找你的)。也就是说,所有的组件都是被动的,所有的组件初始化和调用都由容器负责。组件处在一个容器当中,由容器负责管理。简单的来讲,就是由容器控制程序之间的关系,而非传统实现中,由程序代码直接操控,即在一个类中调用另外一个类。这也就是所谓“控制反转”的概念所在:控制权由应用代码中转到了外部容器,控制权的转移,即所谓反
六、IoC容器的作用
- 创建bean实例
- 根据配置文件装配bean
- 为bean设置初始化参数
- 管理bean的生命周期
网友评论