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