spring IOC 通俗解釋

ZJE_ANDY發表於2020-12-25

目錄

 

一、什麼是IOC

IOC有個別名,叫依賴注入(DI)

為什麼程式碼中用 new 建立物件會增加程式碼的耦合度

那不用 new 建立物件的話,那該如何建立物件?(答案是用注入的方式)

二、IOC實現原理


一、什麼是IOC

IOC的意思是 Inversion of Control ,即控制反轉。

“控制反轉”,不是什麼技術,而是一種設計思想。

IOC的提出是為了解決物件之間耦合程度過高的問題。

傳統的軟體開發的物件A,B,C,D的依賴關係強的話,就會如下圖,我們直接在物件內部通過new進行建立物件,是程式主動去建立依賴物件,從而導致類與類之間高耦合

而IOC容器則像是物件與物件之間的“第三方”,齒輪之間的傳動全部依靠“第三方”了,使得A,B,C,d這4個物件沒有了耦合關係。所以,IOC容器成了整個系統的關鍵核心,它起到了一種類似“粘合劑”的作用,把系統中的所有物件粘合在一起發揮作用,如果沒有這個“粘合劑”,物件與物件之間會彼此失去聯絡,這就是有人把IOC容器比喻成“粘合劑”的由來。

如果把中間的IOC拿掉,那麼就像下圖:物件A,B,C,D

可以看到,拿掉IOC容器後,各個物件(A,B,C,D)之間是基本上沒有耦合的。這樣的話,當你去實現A的時候,就無須考慮B,C,D。所以,如果真能實現IOC容器,對於系統開發而言,這將是一件多麼美好的事情,參與開發的每一成員只要實現自己的類就可以了,跟別人沒有任何關係!

 

IOC有個別名,叫依賴注入(DI)

所謂依賴注入,就是由IOC容器在執行期間,動態地將某種依賴關係注入到物件之中。所以,依賴注入(DI)和控制反轉(IOC)是從不同的角度的描述的同一件事情,指就是通過引入IOC容器,利用依賴關係注入的方式,實現物件之間的解耦

舉個依賴注入例子:

      電腦主機讀取檔案的時候,它一點也不會關心USB介面上連線的是什麼外部裝置,而且它確實也無須知道。它的任務就是讀取USB介面,掛接的外部裝置只要符合USB介面標準即可。所以,如果我給電腦主機連線上一個U盤,那麼主機就從U盤上讀取檔案;如果我給電腦主機連線上一個外接硬碟,那麼電腦主機就從外接硬碟上讀取檔案。掛接外部裝置的權力由我作主,即控制權歸我,至於USB介面掛接的是什麼裝置,電腦主機是決定不了,它只能被動的接受。電腦主機需要外部裝置的時候,根本不用它告訴我,我就會主動幫它掛上它想要的外部裝置,你看我的服務是多麼的到位。這就是我們生活中常見的一個依賴注入的例子。在這個過程中,我就起到了IOC容器的作用。即電腦需要什麼,我就幫它注入什麼,但電腦本身只能被動地接受我給它注入的東西。

 

為什麼程式碼中用 new 建立物件會增加程式碼的耦合度

在傳統的實現中,由程式內部程式碼來控制元件之間的關係。我們經常使用new關鍵字來實現兩個元件之間關係的組合,這種實現方式會造成元件之間耦合。下面有個回答說得不錯:

那不用 new 建立物件的話,那該如何建立物件?(答案是用注入的方式)

如我們定義瞭如下程式碼,Cow 和 Rabbit 類都實現了Animal介面:

Interface Animal{
void eat();
}

Class Cow implements Animal{
public void eat(){System.out.println("牛吃草");}
}

Class Rabbit implements Animal{
public void eat(){System.out.println("兔子吃草");}
}

然後使用時,如下,我們只需要維護一個 Animal型別的引用即可,下面的方法用了 setAnimal()來對 animal 進行物件的注入。這樣的話,MyClass的程式碼邏輯就跟 Cow 和 Rabbit的程式碼邏輯分開,耦合程度降低。因為不管 setAnimal()傳入的是 Cow 還是 Rabbit,都可以用 Animal 來表示。

Class MyClass{
private Animal animal;
public void test(){animal.eat();}
public void setAnimal(Animal a){animal = a;}
}

當然,Springboot中可以用@autowired 註解來做注入,這會更方便。如下:

Class MyClass{
@Autowired
private Animal animal;
xxx
xxx
xxx
}

二、IOC實現原理

IOC可以看作工廠模式+反射機制。我們可以把IOC容器的工作模式看做是工廠模式的昇華,可以把IOC容器看作是一個工廠,這個工廠裡要生產的物件都在配置檔案中給出定義,然後利用程式語言的的反射機制,根據配置檔案中給出的類名生成相應的物件。從實現來看,IOC是把以前在工廠方法裡寫死的物件生成程式碼,改變為由配置檔案來定義,也就是把工廠和物件生成這兩者獨立分隔開來,目的就是提高靈活性和可維護性。

IOC缺點:

由於IOC容器生成物件是通過反射方式,在執行效率上有一定的損耗。如果你要追求執行效率的話,就必須對此進行權衡。

 

 

相關文章