理解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 阅读(607)
评论(1) 编辑 收藏 所属分类:
spring