1.2 依赖注入模式
依赖注入(Dependency Injection)是一个非常简单的概念@H_404_10@,伸手-等待@H_404_10@。(让DIP、IoC滚蛋)
如例程1-5所示,Client依赖于抽象类型(甚至是具体类) IServer,蛋是(1)Client的类体中不创建IServer(子类)的对象@H_404_10@,它不想自己创建IServer对象,而是提供public的构造器Client(IServer)@H_404_10@或设置方法setIServer (IServer)@H_404_10@等(伸手),(2)坐等@H_404_10@外界将初始化后的IServer对象(的引用)传递进来(等待)。
换言之,依赖注入模式是指客户类Client不用自己来初始化它所依赖的成员变量IServer,而是等待某个对象创建IServer的适当的(实现类)的对象并将它赋值给Client的成员变量。
依赖注入的意义@H_404_10@,在于保证Client仅仅与(通常是接口或抽象类)IServer耦合@H_404_10@,而不与IServer的子类型耦合,这样的程序符合OCP或依赖于抽象类型原则。
- 例程@H_404_10@1@H_404_10@-@H_404_10@5@H_404_10@@H_404_10@@H_404_10@
- package@H_404_10@creational;@H_404_10@@H_404_10@
- import@H_404_10@java.lang.reflect.*;@H_404_10@//也可以自己搞@H_404_10@@H_404_10@@H_404_10@
- import@H_404_10@tool.God;@H_404_10@@H_404_10@
- public@H_404_10@@H_404_10@class@H_404_10@Client{@H_404_10@@H_404_10@
- private@H_404_10@IServers;@H_404_10@@H_404_10@
- /**@H_404_10@@H_404_10@
- *依赖注入@H_404_10@@H_404_10@
- */@H_404_10@@H_404_10@@H_404_10@
- public@H_404_10@Client(IServers){@H_404_10@@H_404_10@
- this@H_404_10@.s=s;@H_404_10@@H_404_10@
- }@H_404_10@
- void@H_404_10@setS(IServers){@H_404_10@@H_404_10@
- this@H_404_10@.s=s;@H_404_10@@H_404_10@
- }@H_404_10@
- static@H_404_10@@H_404_10@void@H_404_10@test(){@H_404_10@@H_404_10@
- //使用工具God@H_404_10@@H_404_10@@H_404_10@
- IServers=(IServer)God.create("1-5"@H_404_10@);@H_404_10@@H_404_10@
- s.m();@H_404_10@
- }@H_404_10@
1.2.1 注入的方式
站在Client的角度,Client接受注入@H_404_10@有3种的方式。@H_404_10@
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()方法,这就使得程序员可以在灵活的时间(例如希望惰性初始化@H_404_10@),要求外界完成注入@H_404_10@。
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等待外界或一个独立的对象——称为注射器@H_404_10@——创建IServer的对象并将它赋值给Client的成员变量。现在考察如何设计注射器。
1.显然,这个注射器不应该是应用系统中的一个类: