IoC的全稱是Inversion of Control,中文翻譯反向控制或者逆向控制。這裏的反向是相對EJB來講的。EJB使用JNDI來查找需要的對象,是主動的,而Spring是把依賴的對象注入給相應的類(這裏涉及到另外一個概念“依賴注入”),是被動的,所以稱之爲“反向”。先看一段代碼,這裏的區別就很容易理解了。
代碼片斷1:
public class Container
{
public void init()
{
Speaker s = new Speaker();
Greeting g = new Greeting(s);
}
}
代碼片段2:
public void greet()
{
Speaker s = new Speaker();
s.sayHello();
}
代碼片段3:
public void greet()
{
Speaker s = (Speaker)context.lookup("ejb/Speaker");
s.sayHello();
}
代碼片段4:
public class Greeting
{
public Speaker s;
public Greeting(Speaker s)
{
this.s = s;
}
public void greet()
{
s.sayHello();
}
}
我們可以對比一下這三段代碼。其中片段2是不用容器的編碼,片段3是EJB編碼,片段4是Spring編碼。結合代碼片段1,你能看出來Spring編碼的優越之處嗎?
這裏我想先解釋一下“依賴注入”。根據我給的例子可以看出,Greeting類依賴Speaker類。片段2和片段3都是主動的去獲取Speaker,雖然獲取的方式不同。但是片段4並沒有去獲取或者實例化Speaker類,而是在greeting函數中直接使用了s。你也許很容易就發現了,在構造函數中有一個s被注入(可能你平時用的是,傳入)。在哪裏注入的呢?請回頭看一下代碼片段1,這就是使用容器的好處,由容器來維護各個類之間的依賴關係(一般通過Setter來注入依賴,而不是構造函數,我這裏是爲了簡化示例代碼)。Greeting並不需要關心Speaker是哪裏來的或是從哪裏獲得Speaker,只需要關注自己分內的事情,也就是讓Speaker說一句問候的話。
控制反轉的作用和目的就是應該將組件的配置與使用分離開,使其更具條理化,容易適應變化的環境,或者稱爲解耦合。