IoC,(Inverse of Control)控制反转,其包含两个内容:其一是控制,其二是反转。在程序中,被调用类的选择控制权从调用它的类中移除,转交给第三方裁决。这个第三方指的就是Spring的容器。IoC另解,依赖注入(Dependency Injection),调用类对被调用类的依赖关系由第三方注入,以移除调用类对被调用类的引用。
生活中的Spring IOC解析
说到租房子这件事的时候猛然间就想到了Spring,类似58同城之类的发布信息的网站不就是Spring里面的容器么。网站上有很多别人提供的可以选择的房子(Bean),你所需要做的就是在没有租房子之前想好自己的要求,比如得能洗澡,能做饭,冬暖夏凉,距离上班的地方近(这俨然就是一个定义接口的过程),然后去网上检索寻找合适自己的房子,前提是房东已经主动的将房源信息公布到网上(公布房源信息的过程就是将Bean放入容器的过程,我们寻找房子的过程就类似于Spring中注入的过程,至于是直接注入还是JNDI注入,道理都是一样的,具体方式不一样而已)。找到房子了也就是注入成功了,找不到那只能抛出异常喽。宗旨就是:只要条件满足,房子可以随便换(只要实现了接口,具体注入哪个实现类无关紧要)
基于有向图的Spring IOC解析
从守宏提到聊面试题当中还是学到一些比较有意思的东西,比如:Spring的数学原理----有向图。且不说这个论点对与不对,单就Spring和有向图这两个与“信息与计算科学”专业息息相关的知识点来看,这个论题也是值得自己好好想想的,下面就说说笔者对这句话的理解。
为了方便叙述我们把Spring管理的每一个Bean当做一个节点(假设有N个Bean,那么就有N个节点),于是这些Bean加上相互之间表示调用关系的有向边就组成了一个有向图。毫无疑问,有向图的边越多那么平均来说每个顶点之间的耦合度就越大,最大的情况为完全有向图,即任何两个节点之间都有两条有向边,此时每个顶点的度为2(N-1),也就是说每个Bean与其他的N-1个Bean有耦合,而且还是双向耦合。如下图所示(这里N=3)
众所周知,编程的过程中我们总是强调高内聚、低耦合,要想达到完全的无耦合(如下图)是不可能的。所以最优情况是保持一种松耦合的状态,即在保证实现功能的前提下尽量减少类之间的耦合。我们可以利用接口达到这一目的,通过不同的实现类让调用方对具体实现不再关心,从而达到松耦合的目的。
但是无论耦合多么“松散”具体的实现类还是需要new出来的,于是就得考虑这个new的过程应该放在哪里才是最合适的。如果在每个Bean中都去new这个Bean需要的其他Bean,那么耦合的程度又回到了第一幅图的情况,那是没有意义的。聪明的读者一定想到了如何解决这个问题:找一个中间人,在中间人那里实现new的过程,然后把new好的实例传递给需要这个实例的对象。这样的话一切问题就迎刃而解了,最终的效果如图所示
上图也就是Spring的数学描述,图中很清晰的表明了在使用Spring之后,任意两个节点(Bean)之间的有向线段变成了0(确切的说不完全是0,因为任意两个节点之间还是可以通过容器连接的),唯一和这些Bean有关系的是容器(无论谁需要什么东西都去找容器,尽量避免两个Bean之间直接打交道)也正因为如此Spring才达到了解耦的目的。
所以说,上面提到的“Spring的数学原理是根据有向图而来”这句话是有一定道理的。换个角度去看计算机,从生活,数学或者其他方面也许能把计算机看的更清楚。
文章转自技术大牛郗晓勇 http://blog.csdn.net/beijiguangyong/article/details/8948498