学习过Spring框架的人一定听说过Spring的IoC(InversionofControl)和DI(DependencyInjection)这两个概念。对于初接触Spring的人来说,总觉得IoC和DI这两个概念比较模糊,难以理解。今天和大家分享一下网上一些技术高手对Spring框架IOC的理解,谈谈我对SpringIoc的理解。1.1.什么是国际奥委会?ioc——InversionofControl,即“控制反转”,不是一种技术,而是一种设计思想。在Java开发中,Ioc的意思是将你设计好的对象交给容器来控制,而不是传统的直接控制你的对象内部。如何理解好ioc?理解Ioc的关键是要搞清楚“谁控制谁,控制什么,为什么要反转(有反转就应该有正反转),反转哪些方面”,那么我们来深入分析一下:谁控制谁,控制什么:在传统的JavaSE编程中,我们直接在对象内部通过new创建对象,程序主动创建依赖对象;而IoC有专门的容器来创建这些对象,即Ioc容器控制对象的创建;谁控制谁?当然IoC容器控制对象;控制什么?即主要控制外部资源(不仅仅是对象包括文件等)的获取。●为什么反转,反转了哪些方面:有反转就有正转。传统应用中,我们在对象中主动控制,直接获取依赖对象,即正向旋转;而相反是由容器制成的。帮助创建和注入依赖对象;为什么反转?因为容器帮我们找到并注入了依赖对象,对象只是被动接受依赖对象,所以反过来了;哪些方面是相反的?依赖对象的获取是相反的。举例说明,传统的程序设计如图2-1所示,是主动创建相关对象,然后组合:当有IoC/DI容器时,不再主动在客户端类中创建这些对象。如图2-2所示:1.2、IoC能做什么IoC不是一种技术,而是一种思想,一种重要的面向对象编程法则,它可以指导我们如何设计松散耦合的更好的程序。传统应用中,我们主动在类内部创建依赖对象,导致类间耦合度高,难以测试;使用IoC容器,将创建和查找依赖对象的控制权交给了容器,容器注入组合对象,所以对象是松耦合的,这样也便于测试,有利于功能复用,更重要的是,使得整个程序的架构非常灵活。事实上,IoC给编程带来的最大变化并不是来自代码,而是从思想上发生了“主从换位”的变化。应用本来就是老大,它主动获取任何资源,但是在IoC/DI的思维中,应用变成了被动的,被动地等待IoC容器创建并注入自己需要的资源。IoC很好地体现了面向对象的设计法则之一——好莱坞法则:“不要找我们,我们来找你”;即IoC容器帮助对象找到对应的依赖对象并注入,而不是对象主动寻找。1.3.IoC和DIDI—DependencyInjection,即“依赖注入”:组件之间的依赖关系由容器在运行时决定。说白了就是容器动态的给组件注入一定的依赖关系。依赖注入的目的不是给软件系统带来更多的功能,而是增加组件重用的频率,为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,无需任何代码,指定目标需要的资源,完成自己的业务逻辑,而不用关心具体的资源来自哪里,由谁来实现。理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入什么”,那么我们深入分析一下:●谁依赖谁:当然,应用依赖于国际奥委会容器;●为什么需要依赖:应用需要IoC容器来提供对象需要的外部资源;谁注入谁:很明显,IoC容器注入的是应用程序的一个对象,应用程序所依赖的对象;注入的是什么:就是注入一个对象需要的外部资源(包括对象、资源、常量数据)。IoC和DI是什么关系?实际上,它们是同一概念的不同角度的描述。由于控制反转的概念比较模糊(可能只理解为容器控制对象的层次,人们很难想到谁来维护对象关系),所以2004年大师MartinFowler的新名字是给出:“依赖注入”。与IoC相比,DependencyInjection明确描述了“注入的对象依赖于IoC容器配置的依赖对象”。看了很多关于Spring的Ioc理解的文章。很多人对ioc和DI的解释都是晦涩难懂的。反正就是一种说不清道不明的感觉。看完了,还是一头雾水。感觉像凯涛这种技术天才,很好理解。IoC(InversionofControl)和DI(DependencyInjection)中的每一个字他都解释的清清楚楚。读后给人一种豁然开朗的感觉。相信对于刚接触Spring框架的小伙伴们,对Ioc的理解应该会有很大的帮助。2.1、IoC(InversionofControl)首先我想说说IoC(InversionofControl,控制反转)。这是整个春天的核心。所谓IoC,对于spring框架来说,就是spring负责控制对象的生命周期和对象之间的关系。这是什么意思?举个简单的例子,我们怎么找女朋友?通常的情况是,我们四处转转,??看看哪里有漂亮好看的MM,然后打听她们的爱好,QQ号,电话号码,IP号,智商号……,试着去了解她们,然后dowhattheywant好送他们想要的,然后呵呵……这个过程复杂而深刻,每个环节我们都要自己去设计和面对。传统的程序开发也是如此。在一个对象中,如果要使用另一个对象,必须先获取(自己新建一个,或者从JNDI中查询一个),使用完后销毁该对象(如Connection等)。对象总是耦合到其他接口或类。那么IoC是如何做到的呢?这有点像通过婚介所找女朋友。我和女朋友之间介绍了一个第三方:婚介所。婚介所掌握了很多男女信息。我可以给婚介所提出一个名单,告诉它我想找什么样的女朋友,比如长得像李嘉欣,身材像林熙蕾,唱歌像周杰伦,速度像卡洛斯,技术像气。Dane之类的,然后婚介所会根据我们的要求提供一个mm,我们只需要和她谈恋爱结婚就可以了。简单明了,如果媒人给我们的人选不符合要求,我们就抛出异常。整个过程不再由我自己来控制,而是由婚介所这样一个类似容器的组织来控制。这就是Spring提倡的开发方式。所有的类都会注册到spring容器中,告诉spring你是什么,你需要什么,然后spring会在系统正常运行的时候给你你想要的,同时也把你交给需要你的人。所有类的创建和销毁都由spring控制,也就是说不再是对象引用它,而是spring控制了对象的生命周期。对于一个具体的对象,以前是它去控制其他的对象,现在所有的对象都被spring控制了,所以这叫控制反转。2.2.DI(DependencyInjection)IoC的一个关键点是在系统运行过程中,动态地向一个对象提供它所需要的其他对象。这是通过DI(DependencyInjection,依赖注入)实现的。比如对象A需要操作数据库。以前我们总是要在A中写代码获取一个Connection对象。而有了spring,我们只需要告诉spring,A中需要一个Connection,至于如何以及何时构造这个Connection,A不需要知道。当系统运行时,sp??ring会在适当的时候创建一个Connection,然后像注入一样注入到A中,从而完成对各个对象之间关系的控制。A需要依赖Connection才能正常运行,而这个Connection是由spring注入到A中的,所以依赖注入的名字就是由此而来。那么DI是如何实现的呢?Java1.3之后的一个重要特性是反射,它允许程序在运行时动态生成对象、执行对象方法、改变对象属性。Spring通过反射实现注入。理解了IoC和DI的概念之后,一切都会变得简单明了,剩下的工作就是在spring框架中堆砌block。三、我对IoC(InversionofControl)和DI(DependencyInjection)的理解在正常的java应用开发中,我们至少需要两个或多个对象来实现某个功能或者完成某个业务逻辑。协作完成。在不使用Spring的情况下,每个对象在需要使用自己的协作对象时,必须使用newobject()这样的语法来创建一个协作对象。这个合作对象是自己创建的,创建合作对象的主动权在自己手里。你需要哪个合作对象,你会主动创建。创建协作对象的主动权和时机由自己控制,这会使得对象之间的耦合度很高,A对象需要使用协作对象B共同完成一件事,如果A要使用B,那么A对B有依赖,即A和B之间存在耦合关系,紧耦合在一起,而使用Spring之后就不一样了。创建协作对象B的工作由Spring完成。Spring创建B对象并将其存储在容器中。当A对象需要使用B对象时,Spring开始从存储的对象容器中取出A要使用的B对象,然后交给A对象使用。至于Spring如何创建对象,什么时候创建对象,A对象不需要关心这些细节(whendoyouBorn,我不关心它是怎么诞生的,只要你能帮我干活),A拿到Spring给我们的对象后,他们两个就可以一起完成要完成的工作了。所以控制反转IoC(InversionofControl)指的是转移创建对象的控制权。以前创建对象的主动权和时机都是自己掌握的,现在这个权力交给了第三方,比如交给IoC容器,就是专门用来创建对象的工厂。无论你想要什么对象,它都会给你对象。有了IoC容器,依赖关系就变了,原来的依赖关系没有了。它们都依赖于IoCContainer,它们之间的关系是通过IoC容器建立起来的。这是我对Spring的IoC(InversionofControl)的理解。DI(DependencyInjection)其实是IOC的另一种说法。DI最早是由MartinFowler在2004年初的一篇论文中提出的,他总结道:什么是控制反转?即:获取依赖对象的方式是相反的。4.小结关于SpringIoc的核心概念,相信每个研究Spring的人都会有自己的理解。这种概念上的理解并没有绝对的标准答案,见仁见智。
