spring:Inversion of Control具体实现【资料搜集】

IoC(InversionofControl)控制反转的具体表现为以下几点:

高层模块不应该依赖底层模块,而是模块都必须依赖于抽象。

实现必须依赖抽象,而不是抽象依赖实现。

如果高层模块直接执行底层模块的函数,就对底层模块产生了依赖关系。

在设计上希望模块都依赖与模块的抽象,这样才可以重用高层的应用程序设计。

publicclassBusiness{

privateFloppyWriterwriter=newFloppyWriter();

...

publicvoidsave(){

...

writer.saveToFloppy();

}

}

Business类的设计中,存盘的需求依赖于实际的FloppyWriter对象,如果今天想要将存储介质换为USB磁盘,则必须修改Business的程序,您无法直接重复使用Business类。

如果透过接口的声明,可以改进这种情况,例如可先定义一个IDeviceWriter接口:

publicinterfaceIDeviceWriter{

publicvoidsaveToDevice();

}

接着所设计的Business类,在遇到存盘需求时,可以设计为依赖与IDevice接口,而不是依赖于实际的FloppyWriter,例如:

publicclassBusiness{

privateIDeviceWriterwriter;

publicvoidsetDeviceWriter(IDeviceWriterwriter){

this.writer=writer;

}

publicvoidsave(){

...

writer.saveToDevice();

}

}

在这样的设计下,Business类就是可以重用的,如果今天有存储至Floppy或USB磁盘的需求,只要针对这两种储存需求分别实现接口即可,例如针对Floppy存储设计一个FloppyWriter类:

publicclassFloppyWriterimplementsIDeviceWriter{

publicvoidsaveToDevice(){

...

//实际存储至Floppy的程序代码

}

}

或是针对USB磁盘存储设计一个UsbDiskWriter类:

publicclassUsbDiskWriterimplementsIDeviceWriter{

publicvoidsaveToDevice(){

...

//实际存储至UsbDisk的程序代码

}

如果应用程序需要Floppy存储的话,可以编写一个配置程序如下:

Businessbusiness=newBusiness();

business.setDeviceWriter(newFloppyWriter());

business.save();

同样的,如果应用程序需要USB磁盘的话,可以编写一个配置程序如下:

Businessbusiness=newBusiness();

business.setDeviceWriter(newUsbDiskWriter());

business.save();

IoC要求的是容器不应该(或尽量不要)侵入应用程序,也就是不应该出现与容器相依的API,应用程序本身可以依赖于抽象的接口,容器可以透过这些抽象接口将所需的资源注入至应用程序中,应用程序不向容器主动要求资源,故而不会依赖于容器的特定API,应用程序本身不会意识到正被容器使用,可以随时从容器系统中脱离,转移至其他的容器或框架而不用作任何的修改。

IoC模式基本上是一个高层的模式概念,在MartinFowler的InversionofControlContainersandtheDependencyInjectionpattern中谈到,实现IoC有两种方式:DependencyInjection与ServiceLocator,Spring所采用的是DependencyInjection来实现IoC,中文翻译为依赖注入。

Spring的核心是个IoC容器,可以用Setter或构造函数的方式来实现您的应用程序对象,至于对象与独享之间的关系建立,则可以透过配置文件设定(一个XML文件或是一个.properies文件),让Spring在执行时期根据配置文件的设定,为您建立对象之间的依赖关系,您不必特地编写一些程序来自行建立这些对象之间的依赖关系,这不仅减少大量的程序编写,也降低了对象之间的耦合程度。