您的位置:首页 > 编程语言 > Java开发

Spring IOC 学习笔记(一) IoC和DI概述

2007-09-04 21:55 549 查看
在实际的开发中,我们反复尽量避免尽量降低对象间的依赖关系即耦合度。但是如何才能作到呢? 通常的业务对象之间都是依赖关系的,业务对象与业务对象,业务对象与持久层,业务对象与各种资源之间都存在这样和那样的依赖关系。

[align=left]IoC (Inversion Of Control)中文名为控制反转,就是由容器来控制业务对象之间的依赖关系,而非传统实现中,由代码直接操控。这也就是所谓“控制反转”的概念所在:控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转。控制权的转移带来的好处就是降低了业务对象之间的依赖程度。[/align]
[align=left] [/align]
[align=left]IoC实现策略:[/align]
[align=left] [/align]
[align=left]1) 依赖查找:容器中的受控对象通过容器的API来查找自己所依赖的资源和协作对象。这种方式虽然降低了对象间的依赖,但是同时也使用到了容器的API,造成了我们无法在容器外使用和测试对象。[/align]
[align=left] [/align]
[align=left]2) 依赖注入:对象只提供普通的方法让容器去决定依赖关系,容器全权负责组件的装配,它会把符合依赖关系的对象通过属性(JavaBean中的 getter和setter,.NET中的property)或者是构造子传递给需要的对象。通过属性注射依赖关系的做法称为设值方法注入(Setter Injection),将构造子参数传入的做法称为构造子注入(Constructor Injection)[/align]
[align=left] [/align]
[align=left]IoC的第二种策略 依赖注入是一种更加合适的方法。让容器去全权负责依赖查询,受控对象只要暴露属性和代参数的构造子,使容器可以在初始化对象的时候设置对象间的依赖关系。这种方式往往不需要依赖特定API和接口,完全只要依赖语言本身就可以实现了。Spring之父Rod Johnson称之为language-based IoC。[/align]
[align=left] [/align]
[align=left]这样做的好处:[/align]
[align=left]1) 查询依赖操作和应用代码分离。[/align]
[align=left]2) 受控对象不会使用到容器的特定的API。这样我们的受控对象可以搬出容器单独使用。[/align]
[align=left] [/align]
[align=left]现在让我们来看看依赖注入的两种实现方法。[/align]
[align=left] [/align]
[align=left](一)设值方法注入(Setter Injection)[/align]
[align=left] [/align]
[align=left]使用设值方法注入的时候,受控对象通过属性来表达自己所依赖的对象和所需配置的值。Java实现中,只要对象提供JavaBean标准的属性就可以了。例如:[/align]
[align=left] [/align]
[align=left]public class MyBusinessObject {[/align]
[align=left]private DataSource ds;[/align]
[align=left] [/align]
[align=left]public DataSource getDataSource() {[/align]
[align=left] return ds;[/align]
[align=left]}[/align]
[align=left] [/align]
[align=left]public void setDataSource(DataSource ds) {[/align]
[align=left] this.ds = ds;[/align]
[align=left]}[/align]
[align=left] [/align]
[align=left]// 具体的业务逻辑[/align]
[align=left]}[/align]
[align=left]这样当容器实例化对象MyBusinessObject的时候,会立即调用设值方法,将所需的DataSource传递给MyBusinessObject。[/align]
[align=left] [/align]
[align=left]可以看出MyBusinessObject只是一个普通的Java对象,完全没有依赖IoC容器。这样它就可以在容器外运行。[/align]
[align=left] [/align]
[align=left](二)构造子注入(Constructor Injection[/align]
[align=left]如果使用构造子注入MyBusinessObject大概会是这样的。[/align]
[align=left]public class MyBusinessObject {[/align]
[align=left]private DataSource ds;[/align]
[align=left] [/align]
[align=left]public MyBusinessObject(DataSource ds) {[/align]
[align=left] this.ds = ds;[/align]
[align=left]}[/align]
[align=left] [/align]
[align=left]// 具体的业务逻辑[/align]
[align=left]}[/align]
[align=left]可以看出这也是一个简单的Java对象,它也同样不依赖IoC容器。[/align]
[align=left] [/align]
[align=left]比起以前在应用代码中的查找,创建依赖对象的方法来看,这两种注入方法都有着巨大的进步。但是我们该如何选择呢。到底是使用设值方法注入还是构造子注入呢。[/align]
[align=left] [/align]
[align=left]让我先来看看这两种方法的优缺点。[/align]
[align=left] [/align]
[align=left]设值方法注入的主要优点:[/align]
[align=left]1) 每个设值方法都有一个对应的读取方法,这样就可以要求受控对象汇报自身的状态。[/align]
[align=left]2) 父类的属性可以被子类继承而无需重新编码。[/align]
[align=left] [/align]
[align=left]设值方法注入的主要缺点:[/align]
[align=left]1) 设置方法的调用次序无法规定[/align]
[align=left]2) 在使用对象前,可能存在不是所有的设值方法都会调用到,可能存在着未配置完全的状态。[/align]
[align=left] [/align]
[align=left]构造子注入的主要优点:[/align]
[align=left]1) 在使用之前,对象必定处于配置完全的状态。[/align]
[align=left]2) 比起多个设值方法来说一个构造函数的代码量可能更少,当然两者的复杂程度是没有区别的。[/align]
[align=left][/align]
[align=left]构造子注入的主要缺点:[/align]
[align=left]1) 构造子无法被自动被继承。[/align]
[align=left]2) 构造子参数太多和构造子操作太多都不方便于使用[/align]
[align=left]3) IDE对设值方式要比构造子参数列表有更好的支持。[/align]
[align=left] [/align]
[align=left]由此可见在下列情况下,设值方法注入更有优势:[/align]
[align=left]1) 需要配置的属性很多[/align]
[align=left]2) 对象位于继承体系中[/align]
[align=left]3) 对象必须提供运行时修改依赖关系的途径(我认为这点是最主要的)[/align]
[align=left] [/align]
[align=left] [/align]
[align=left] [/align]
[align=left]以上是本人学习Spring的时候对IoC和DI的一些理解。虽然大部分都来自于Rod Johnson的《export one-on-one J2EE Development without EJB》。[/align]
[align=left] [/align]
[align=left]参考:[/align]
[align=left] Rod Johnson的《export one-on-one J2EE Development without EJB》。[/align]
[align=left] 夏昕的《Spring 开发指南》[/align]

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=673148
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: