1.2 依赖注入模式
依赖注入(Dependency Injection)是一个非常简单的概念,伸手-等待。(让DIP、IoC滚蛋)
如例程1-5所示,Client依赖于抽象类型(甚至是具体类) IServer,蛋是(1)Client的类体中不创建IServer(子类)的对象,它不想自己创建IServer对象,而是提供public的构造器Client(IServer)或设置方法setIServer (IServer)等(伸手),(2)坐等外界将初始化后的IServer对象(的引用)传递进来(等待)。
换言之,依赖注入模式是指客户类Client不用自己来初始化它所依赖的成员变量IServer,而是等待某个对象创建IServer的适当的(实现类)的对象并将它赋值给Client的成员变量。
依赖注入的意义,在于保证Client仅仅与(通常是接口或抽象类)IServer耦合,而不与IServer的子类型耦合,这样的程序符合OCP或依赖于抽象类型原则。
- 例程1-5
- packagecreational;
- importjava.lang.reflect.*;//也可以自己搞
- importtool.God;
- publicclassClient{
- privateIServers;
- /**
- *依赖注入
- */
- publicClient(IServers){
- this.s=s;
- }
- voidsetS(IServers){
- this.s=s;
- }
- staticvoidtest(){
- //使用工具God
- IServers=(IServer)God.create("1-5");
- s.m();
- }
1.2.1 注入的方式
站在Client的角度,Client接受注入有3种的方式。
1.构造器注入(Constructor Injection)
客户类Client提供了public的构造器Client (IServer s),等待外界创建IServer的(实现类的)对象后将其引用传递进来/注入。
publicClient(IServer s){
this.s=s;
}
2.Setter注入
Setter注入(Setter Injection)时,客户类Client提供setIServer (IServers),等待外界创建IServer的(实现类的)对象后将其引用传递进来/注入。
publicvoid setIServer (IServer s){
this.s=s;
}
构造器注入与Setter注入是两种常用的方式。构造器注入的优点是创建Client对象时,确保IServer对象被初始化;而采用Setter注入,则创建Client对象后,必须在适当的时候调用setIServer()方法,这就使得程序员可以在灵活的时间(例如希望惰性初始化),要求外界完成注入。
3.接口注入
接口注入相当于将Setter注入的setIServer (IServer s) 方法封装到一个专用的接口如InjectIServer中,而Client实现InjectIServer并给出如下的方法体。
@Overridepublic void setIServer (IServer s){
this.s=s;
}
接口注入针对的场景是,有大量Client、Client1等都需要依赖于IServer。
public interface InjectIServer{
publicvoid setIServer (IServer s);
}
代码中使用了[4.1虚域模式]。然而这一方式并不一定被各种依赖注入容器所支持。
1.2.2 依赖注入容器/框架
依赖注入模式中,Client等待外界或一个独立的对象——称为注射器——创建IServer的对象并将它赋值给Client的成员变量。现在考察如何设计注射器。
1.显然,这个注射器不应该是应用系统中的一个类: