IoC的引入


八月的第一周,我们来说IoC

IoC是Spring框架的核心思想其一,原理不算复杂。


Spring家族是Java中风光无限的一族,几乎所有Java项目所使用的框架,都跟Spring家族有关。有一些介绍中说,Spring框架是一种全栈式框架(或者是一站式框架),全栈(Full-stack)的意思就是说,编程里能干的所有活,它一家可以全包了,一条龙服务,可以应用于一切场景。

Spring在2004年发布了1.0版本。创建Spring的那哥们叫Rod Johnson,他自己写了本书,说当时的主流框架EJB可以换个思路写代码,后来觉得不痛快,就又写了一本书,说我们干脆换个框架算了,于是就有了Spring。说起来这哥们也是个神人,他本科计算机专业毕业的,然后读了个音乐博士。

Spring现在那么盛行,几乎所有公司都在用Spring框架,倒不是因为技术、架构这些,而是跟思想有关。一说思想这个词,一般事情就变得玄妙了起来,简单点说呢,用Spring这套模式写代码,写起来感觉得心应手,少了很多麻烦,写着写着代码冥冥之中感觉很轻便,这就是因为Spring在思想上很先进。Spring的核心思想有两种,一种是IoC,一种是AOP,我们今天说前面那个IoC。


IoC的全称是Inversion of Control,翻译过来叫控制反转。这并不是一个见名知意的名词,首先要解释一下这个概念。

好比我现在要制造一辆汽车,从无到有一步一步地建造。

首先我要先制造出汽车底盘,根据底盘的大小来确定汽车的外壳有多大。如果我建造了一个5米长的底盘,我不可能再建造一个10米长的汽车外壳,装不上去呀。所以你发现了,汽车外壳必须要根据汽车底盘来制造,这也就是汽车外壳依赖于汽车底盘,换句话说,我们造外壳的时候,是被底盘牵着鼻子走的。

对于有设计欲望的汽车制造师来讲,这很让人不爽,明明我要大显身手地去设计汽车外壳,让自己的车外观上十分拉风,结果却要根据汽车底盘来设计,这不行。因此我们找到了一家汽车零件厂,我就先造外壳,造完之后需要多大的底盘,去找汽车零件厂给我提供。让汽车制造师一番折腾,现在可以直接造汽车外壳,然后再管汽车底盘了。汽车底盘反依赖于汽车外壳,也就是说,底盘被外壳牵着鼻子走了。

我们要讨论的IoC控制反转,这里的控制,其实说的就是谁牵着谁鼻子走。按照原先的理解,A是B的底层,A要控制B;现在B先行,A跟着B走,B反而控制A了,这就是控制反转。

你应该感受到了,Ioc并不是什么具体的技术,而是一种思想,或者更确切地说是一种设计模式。


我们说了半天控制反转,怎么控制的,怎么反转的,都快绕晕了。其实谁控制谁根本就不重要,不管是A控制B还是B控制A,也没什么区别,反转了又能怎么样嘛。

关键是在于,原来A控制B,那是一点点往上搭积木,A也得搭,B也得搭。控制反转之后,现在B还是要做,但是A怎么来的,我们就不管了。

就像是刚才举的造汽车的例子,原来汽车是怎么造的,先造底盘,再造外壳,一步一步地很是繁琐,约束还多。后来我们只造外壳,那底盘呢,底盘让汽车零件厂造去了,我们不造了。怎么来的我也不管,反正到时候你给我就行了。

你说是不是省很多事?

总结一下,IoC思想有两点好处:

  • 其一,再也不用写一大堆的初始化代码了,这些扔给别人去做。
  • 其二(这个更重要),我们把代码松绑了,原本紧密依赖的两部分如今拆开了,用祖师爷的话说就是“降低了耦合度”。

我们再来聊Spring。

Spring框架实现IoC主要是这样子的,它在A类和B类之外增设了一个管理区,A类写好之后放进管理区里,B类要用A类的时候就去找管理区,管理区自动为B类分配。

知乎上有个哥们挺逗的,他这么形容Spring实现IoC的过程:

农业社会中,你需要一个对象,你必须亲手把它 new 出来。

工业社会中,你需要一个对象,可以去工厂那里获取。

共产主义社会中,你需要一个对象,只需要凭 ID 去对象池里面领。

这是何等的共产主义精神!

让Spring这么一处理,对于B类而言,原来是自己主动获取A类,现在是需要的时候管理区自动给我(用术语来说,这一步叫做注入),原来A类相关的代码都是自己管理,现在交给管理区去管理。这就叫做“降低了代码之间的耦合性”。

这个管理区叫做IoC容器,容器(Container)是编程里面装东西的。

好的,我们说的概念已经够多了,就说到这里吧。关于Spring实现IoC的具体过程,我们之后再说吧。