ioc意味着将你设计好的交给容器控制,而不是传统在你的对象中直接控制
谁控制了谁:传统的javaSE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而ioc是有专门一个容器来创建这些对象,即由ioc容器来控制对象的创建;当然是IoC 容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。
哪些方面反转:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接或去依赖对象,也就是正转;而反转则是有容器帮忙创建及注入依赖对象。因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。
所谓的ioc,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系
那么IoC是如何做的呢?有点像通过婚介找女朋友,在我和女朋友之间引入了一个第三者:婚姻介绍所。婚介管理了很多男男女女的资料,我可以向婚介提出一个列表,告诉它我想找个什么样的女朋友,比如长得像李嘉欣,身材像林熙雷,唱歌像周杰伦,速度像卡洛斯,技术像齐达内之类的,然后婚介就会按照我们的要求,提供一个mm,我们只需要去和她谈恋爱、结婚就行了。简单明了,如果婚介给我们的人选不符合要求,我们就会抛出异常。整个过程不再由我自己控制,而是有婚介这样一个类似容器的机构来控制。
Spring所倡导的开发方式就是如此,所有的类都会在spring容器中登记,告诉spring你是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。
设计模式
IoC可以认为是一种全新的设计模式,但是理论和时间成熟相对较晚,并没有包含在GoF中。
Interface Driven Design接口驱动,接口驱动有很多好处,可以提供不同灵活的子类实现,增加代码稳定和健壮性等等,但是接口一定是需要实现的,也就是如下语句迟早要执行:AInterface a = new AInterfaceImp(); 这样一来,耦合关系就产生了
classA { AInterface a; A(){} AMethod()//一个方法 { a = new AInterfaceImp(); } }
Class A与AInterfaceImp就是依赖关系,如果想使用AInterface的另外一个实现就需要更改代码了。当然我们可以建立一个Factory来根据条件生成想要的AInterface的具体实现,即:
InterfaceImplFactory { AInterface create(Object condition) { if(condition == condA) { return new AInterfaceImpA(); } else if(condition == condB) { return new AInterfaceImpB(); } else { return new AInterfaceImp(); } } }
DI -- Dependency Injection,依赖注入
即组件之间的依赖关系由容器在运行期决定,形象的来说,即由容器动态的将某种依赖关系注入到组件之中. 依赖注入的目标并非为软件系统带来更多的功能,而是为了提升组件重用的概率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不用关心具体的资源来自何处、由谁实现.
理解DI的关键是 "谁依赖谁,为什么需要依赖, 谁注入谁,注入了什么",下面来深入分析一下:
谁依赖于谁 : 应用程序依赖于IoC/DI容器
为什么需要依赖 : 因为反转后,应用程序所依赖都资源都在IoC/DI容器中
谁注入谁 : IoC/DI容器注入应用程序
注入了什么: 注入了应用程序需要的外部资源,比如:依赖关系
控制反转和依赖注入之间是同一个概念吗?
它们不是同一个概念,但是它们是同一个概念的不同角度的描述。
控制反转(IoC)从 IoC容器的角度来说
依赖注入(DI) 从应用程序的角度来说
ioc与di的区别
DI就是斧头,ioc就是树,最好的办法就是用斧头砍树。
当然可以不用斧头,所以ioc不一定需要DI,也可以有别的方案。
当然斧头不必砍树,斧头能做的事情好多,不过一般用来砍树。