理解IoC的概念
IoC全稱Inversion of Control,直譯為控制反轉(zhuǎn).何謂IoC?在解釋此概念之前,我們來看看下面的例子
import ...
public class BookService {
private BookDAO bookDAO = new DbBookDAO();
public List<Book> listBooks(String author) {
List<Book> books = bookDAO.listAll();
return books ;
}
}
可以看到,listBooks方法的功能非常簡單,即列出所有書籍.而列出所有書籍的功能被委托給bookDAO對象.
考慮到書籍可能存在多種形式,如數(shù)據(jù)庫,XML文件等,將BookDAO申明為接口,因此我們實現(xiàn)了一個具體
子類DbBookDAO.
現(xiàn)在需要考慮的是,BookService如何持有bookDAO對象.最簡單的辦法是,在BookService的內(nèi)部持有
一個DbBookDAO的實例,上面的例子確實是這么做的.考慮一下會發(fā)現(xiàn)以下的問題:
(1)在BookService中硬編碼創(chuàng)建了BookDAO,如果需要另一種BookDAO的實現(xiàn),則需要修改BookService的
代碼,換句話就是BookService組件不能脫離BookDAO的具體實現(xiàn).
(2)BookDAO的實例無法被其它組件共享.假設(shè)其它的組件也需要引用BookDAO,則多個組件很難共享一個
BookDAO實例,因為該實例的生命周期定義在了BookService組件中了,從而難以共享.
(3)如果BookDAO仍需要引用其它資源,例如DataSource,則BookService可能還需要負(fù)責(zé)管理和維護(hù)一個
DataSource,而這實例不是作為上層組件BookService的職責(zé).
(4)測試BookService是復(fù)雜的,因為首先編寫DbBookDAO,倘若DbBookDAO還依賴于DataSource,是相當(dāng)復(fù)雜.
從以上幾點可以看出,如果系統(tǒng)中有大量的組件,其它生命周期和相互之間的依賴關(guān)系,如果由組件
自己維護(hù),不但加大的系統(tǒng)的復(fù)雜度,而且會導(dǎo)致組件之間的極為緊密的耦合,繼而給測試和維護(hù)帶來了
極大的困難.
在IoC模式下,控制權(quán)發(fā)生了反轉(zhuǎn):從應(yīng)用程序轉(zhuǎn)移到了IoC容器.組件不再由應(yīng)用程序負(fù)責(zé)創(chuàng)建和配置
而是由容器負(fù)責(zé),應(yīng)用程序只需直接使用已經(jīng)創(chuàng)建并配置好的組件.
import ...
public class BookService {
private BookDAO bookDAO ;
public void setBookDAO(BookDAO bookDAO) {
this.bookDAO = bookDAO ;
}
public List<Book> listBooks(String author) {
List<Book> books = bookDAO.listAll();
return books ;
}
}
修改后的bookDAO實例不再由BookService創(chuàng)建,而是由IoC容器負(fù)責(zé)將某個BookDAO實例通過setBookDAO()
注入.這樣做的好處:
(1)BookService不必關(guān)心如何創(chuàng)建BookDAO的實例,也不必關(guān)心BookDAO的具體實現(xiàn),只需要使用它就可以了
因此簡化了BookService的編碼.
(2)BookDAO的實例由IoC容器管理,因此,可以在多個組件之間共享,只要它們也實現(xiàn)了相應(yīng)的setBookDAO()
方法就可以了.
(3)測試BookService也變成十分容易了.
IoC容器負(fù)責(zé)實例化所有的組件,因此需要告訴容器如何創(chuàng)建組件和各組件之間的依賴關(guān)系.
posted on 2007-10-21 12:59
Ke 閱讀(610)
評論(1) 編輯 收藏 所屬分類:
spring