Spring框架中的控制反轉(zhuǎn)(IoC),本來是一個(gè)很簡單的概念,但是在網(wǎng)上卻常常被人亂解釋一通,人云亦云的結(jié)果就是混亂和難以理解。
我們先來看一下網(wǎng)上流行的解釋是怎么說的:
誰控制誰,控制什么:傳統(tǒng)Java SE程序設(shè)計(jì),我們直接在對象內(nèi)部通過new進(jìn)行創(chuàng)建對象,是程序主動(dòng)去創(chuàng)建依賴對象;而IoC是有專門一個(gè)容器來創(chuàng)建這些對象,即由Ioc容器來控制對 象的創(chuàng)建;誰控制誰?當(dāng)然是IoC 容器控制了對象;控制什么?那就是主要控制了外部資源獲?。ú恢皇菍ο蟀ū热缥募龋?/b>
為何是反轉(zhuǎn),哪些方面反轉(zhuǎn)了:有反轉(zhuǎn)就有正轉(zhuǎn),傳統(tǒng)應(yīng)用程序是由我們自己在對象中主動(dòng)控制去直接獲取依賴對象,也就是正轉(zhuǎn);而反轉(zhuǎn)則是由容器來幫忙創(chuàng)建及注入依賴對象;為何是反轉(zhuǎn)?因?yàn)橛扇萜鲙臀覀儾檎壹白⑷胍蕾噷ο?,對象只是被?dòng)的接受依賴對象,所以是反轉(zhuǎn);哪些方面反轉(zhuǎn)了?依賴對象的獲取被反轉(zhuǎn)了。
以上說法其實(shí)只涉及到了IoC的一個(gè)應(yīng)用場景(依賴控制),依賴控制雖然是一種常用場景,但是通過了依賴控制來理解IoC就一定會(huì)把Ioc與依賴注入(DI)搞混淆,越描越黑,徹底分不開了。
早在2004年,Martin Fowler大神的一篇博文討論了IoC,網(wǎng)上很多討論IoC的文章都提到了Martin Fowler,但是我相信很多人都沒有看過原文
https://martinfowler.com/bliki/InversionOfControl.html
我們來看下Martin Fowler是怎么說的:
The control is inverted - it calls me rather me calling the framework.?
控制是反向的-它(框架)調(diào)用我,而不是我調(diào)用框架。
Inversion of Control is a key part of what makes a framework different to a library.?
控制反轉(zhuǎn)是使得框架與庫不同的關(guān)鍵部分。
A library is essentially a set of functions that you can call, these days usually organized into classes. Each call does some work and returns control to the client.
庫本質(zhì)上是您可以調(diào)用的一組函數(shù),這些函數(shù)通常組織成類。每個(gè)調(diào)用都會(huì)執(zhí)行一些工作,并將控制權(quán)返回給客戶端。
A framework embodies some abstract design, with more behavior built in. In order to use it you need to insert your behavior into various places in the framework either by subclassing or by plugging in your own classes. The framework's code then calls your code at these points.
框架體現(xiàn)了一些抽象設(shè)計(jì),并內(nèi)置了更多行為。要使用它,您需要通過子類化或插入自己的類將行為插入到框架中的不同位置。然后,框架的代碼在這些位置調(diào)用您的代碼。
看明白了嗎?一句話:控制反轉(zhuǎn)就是把程序執(zhí)行過程由原來的程序員控制轉(zhuǎn)向由框架來控制,這就是框架與庫(lib)最關(guān)鍵的區(qū)別。
所以依賴注入只是IoC的一部分應(yīng)用場景而已,其實(shí)你每次在別人定義的回調(diào)函數(shù)中寫代碼都是控制反轉(zhuǎn)。