IoC,直觀地講,就是容器控制程序之間的關係,而非傳統實現中,由程序代碼直接操控。這也就是所謂「控制反轉」的概念所在。控制權由應用代碼中轉 到了外部容器,控制權的轉移是所謂反轉。IoC還有另一個名字——「依賴注入(Dependency Injection)」。從名字上理解,所謂依賴注入,即組件之間的依賴關係由容器在運行期決定,形象地說,即由容器動態地將某種依賴關係注入到組件之 中。
下面經過一個生動形象的例子介紹控制反轉。
this
好比,一個女孩但願找到合適的男友,如圖6-2所示,能夠有3種方式,即兩小無猜、親友介紹、父母包辦。.net
第1種方式是兩小無猜,如圖6-3所示。 component
經過代碼表示以下。
public class Girl {
void kiss(){
Boy boy = new Boy();
}
}
第2種方式是親友介紹,如圖6-4所示。
對象
經過代碼表示以下。
public class Girl {
void kiss(){
Boy boy = BoyFactory.createBoy();
}
}
第3種方式是父母包辦,如圖6-5所示。
接口
經過代碼表示以下。
public class Girl {
void kiss(Boy boy){
// kiss boy
boy.kiss();
}
}
哪種爲控制反轉IoC呢?雖然在現實生活中咱們都但願兩小無猜,但在Spring世界裏,選擇的倒是父母包辦,它就是控制反轉,而這裏具備控制力的父母,就是Spring所謂的容器概念。
典型的IoC能夠如圖6-6所示。
資源
IoC的3種依賴注入類型以下。
第1種是經過接口注射,這種方式要求咱們的類必須實現容器給定的一個接口,而後容器會利用這個接口給咱們這個類注射它所依賴的類。
public class Girl implements Servicable {
Kissable kissable;
public void service(ServiceManager mgr) {
kissable = (Kissable) mgr.lookup("kissable");
}
public void kissYourKissable() {
kissable.kiss();
}
}
<container>
<component name="kissable" class="Boy">
<configuration> … </configuration>
</component>
<component name="girl" class="Girl" />
</container>
第2種是經過setter方法注射,這種方式也是Spring推薦的方式。
public class Girl {
private Kissable kissable;
public void setKissable(Kissable kissable) {
this.kissable = kissable;
}
public void kissYourKissable() {
kissable.kiss();
}
}
<beans>
<bean id="boy" class="Boy"/>
<bean id="girl" class="Girl">
<property name="kissable">
<ref bean="boy"/>
</property>
</bean>
</beans>
第3種是經過構造方法注射類,這種方式Spring一樣給予了實現,它和經過setter方式同樣,都在類裏無任何侵入性,可是,不是沒有侵入性,只是把侵入性轉移了,顯然第1種方式要求實現特定的接口,侵入性很是強,不方便之後移植。
public class Girl {
private Kissable kissable;
public Girl(Kissable kissable) {
this.kissable = kissable;
}
public void kissYourKissable() {
kissable.kiss();
}
}
PicoContainer container = new DefaultPicoContainer();
container.registerComponentImplementation(Boy.class);
container.registerComponentImplementation(Girl.class);
Girl girl = (Girl) container.getComponentInstance(Girl.class);
girl.kissYourKissable(); get
IOC是Spring的核心。IOC,控制反轉,指應用程序不對依賴對象進行建立與維護,依賴對象的建立與維護有外部容器(也就是Spring容 器)負責。通俗的說,就是咱們不在類的內部new一個對象了,new對象的操做交給外部容器來作,這樣控制權就從應用程序轉移到了外部容器,即所謂的反 轉。
那麼,將對象的建立交給外部容器來作,外部容器又是怎樣建立對象的呢?這裏就用到DI(也就是依賴注入)了,所謂的DI就是指在運行時,由外部容器動態地 將依賴對象注入到組件中。在網上看見有人說,控制反轉就是注入依賴。後來查了一下,這是不對的,依賴注入實際上是IOC的一種特殊形式,IOC分爲依賴注入 和依賴查找兩種。依賴注入又分爲構造方法依賴注入和設置方法依賴注入,而依賴查找分爲依賴拖拽和上下文依賴查詢。
依賴注入。當咱們須要使用組件前就須要依賴實例的話,咱們應該使用構造方法注入。其實咱們最經常使用到的仍是設置方法注入,他是侵入性最低的注入機制。Spring同時支持兩種方式的注入。
依賴查找。BeanFactory是Spring IOC容器的核心,它負責管理組件和他們之間的依賴。在Spring中,bean表示任何受容器管理的組件,在必定程度上遵循JavaBean規範,但不 是必須的。BeanFactory.getBean(beanName)就是對bean進行查找。在上下文依賴查找中,查找的過程是在容器管理的資源中進 行的,而不是在集中的註冊表中,而且一般是做用於某些設置點上。
此外,在網上看見這樣一句話來形容IOC,以爲頗有意思,拿來講說:
一、未用IOC:一我的揹着一大包炸藥去炸敵人的一座碉堡
二、採用IOC:這我的什麼都不帶跑到敵人碉堡下,而後打電話給總部說,把炸藥給我扔過來。io