这一节主要简单介绍了依赖注入的思想
强调了依赖注入是Spring框架的一种核心模式
下面简单的说明了这种依赖注入的情况客户端使用到了另一个我们称为service的类客户端有自己的属性用来接受这个service这个service被包装成一个接口因此客户端是看不到service的具体实现的但是这个并不完全是松耦合的我们仍然要自己创建service在依赖注入的思想里一种第三方的控制器或装配器用来创建一个客户端和一个service然后set一个service的引用来满足依赖注入的要求
其实我们并不一定需要一个轻量级容器来使用依赖注入的模式我们只需要三步就可以使用依赖注入模式来完成模块的解耦
将这个service类包装成一个接口
给客户端添加一个属性做为这个service接口的引用
使用一个第三方框架或自己编写的代码来开发这个service并设置该属性
下面我们来看如何改写第一节里的范例代码
Example ArrayListRentABikejava (renamed from RentABikejava)
import javautil*;
public class ArrayListRentABike implements RentABike
{
private String storeName;
final List bikes = new ArrayList( );
public ArrayListRentABike( ) { initBikes( ); }
public ArrayListRentABike(String storeName)
{
thisstoreName = storeName;
initBikes( );
}
public void initBikes( )
{
bikesadd(new Bike(Shimano Roadmaster Fair));
bikesadd(new Bike(Cannondale F XTR Excellent));
bikesadd(new Bike(Trek Fair));
}
public String toString( ) { return RentABike: + storeName; }
public List getBikes( ) { return bikes; }
public Bike getBike(String serialNo) { Iterator iter = bikesiterator( );
while(iterhasNext( ))
{
Bike bike = (Bike)iternext( );
if(serialNoequals(bikegetSerialNo( ))) return bike;
}
return null;
}
}
Example RentABikejava
import javautil*;interface RentABike { List getBikes( ); Bike getBike(String serialNo);}
大家看到了RentABike由原来的具体类改成了一个接口而具体实现类是由ArrayListRentABike来完成的实现类里的操作和方法和第一节里的原RentABike是一模一样的
再来看看客户端的代码
Example CommandLineViewjava
import javautil*;
public class CommandLineView
{
private RentABike rentaBike;//接口的引用
public CommandLineView( ) { } //set接口
public void setRentaBike(RentABike rentaBike) {thisrentaBike = rentaBike;}
public RentABike getRentaBike( ) { return thisrentaBike;}
public void printAllBikes( )
{
Systemoutprintln(rentaBiketoString( ));
Iterator iter = rentaBikegetBikes( )iterator( );
while(iterhasNext( ))
{
Bike bike = (Bike)iternext( );
Systemoutprintln(biketoString( ));
}
}
}
大家应该注意到了吧这里客户端有一个属性放置RentABike接口的引用
最后我们有一个控制器或装配器来创建所有的对象并设置它们的属性
Example RentABikeAssemblerjava
public class RentABikeAssembler
{
public static final void main(String[] args)
{
//创建一个客户端对象
CommandLineView clv = new CommandLineView( );
//装配器给出了接口的具体实现所谓面向接口的编程
RentABike rentaBike = new ArrayListRentABike(Bruces Bikes);
//设置客户端对象的属性将接口通过构造方法的模式注入
clvsetRentaBike(rentaBike);
//调用客户端对象的内部方法
clvprintAllBikes( );
}
}
实际上以上操作就完成了三个步骤的依赖注入模式
我们运行程序可以得到和第一节同样的结果
C:\RentABikeApp\out>java RentABikeAssembler
RentABike: Bruces Bikes
Bike : manufacturer Shimano
: model Roadmaster
: frame
: serialNo
: weight
: status Fair
Bike : manufacturer Cannondale
: model F XTR
: frame
: serialNo
: weight
: status Excellent
Bike : manufacturer Trek
: model
: frame
: serialNo
: weight
: status Fair
大家现在看到了一个不用特定容器而实现的简单的依赖注入通过一个装配器来完成注入操作其实最终这个装配器会用Spring框架来取代Spring会为我们创建对象和设置属性
下面是JEE应用程序使用service locator来管理其依赖service locator是JEE核心设计模式之一它经常被用在命名和服务定位上
service location这种设计模式把依赖从应用程序中完全脱离了出来我们后面会陆续讲到