什么是IoC?
“依赖注入(DI)”有时候也被称为“控制反转(IoC)”本质上它们是同一个概念。具体是指,当某个类调用另外一个类的时候通常需要调用者来创建被调用者。但在控制反转的情况下调用者不在主动创建被调用者,而是改为由容器注入,因此而得名。这里的“创建”强调的是调用者的主动性。而依赖注入则不在需要调用者主动创建被调用者。
举个例子通常情况下调用者(ClassA),会先创建好被调用者(FunBean),然后在调用方法callFoo中调用被调用者(FunBean)的foo方法:
例如
public class ClassA {
private FunBean funBean = new FunBean();
public void callFoo() {
this.funBean.foo();
}
}
public class FunBean {
public void foo() {
System.out.println("say ...");
}
}
使用了依赖注入的情况恰恰相反,调用者(ClassA)事先并不知道要创建哪个被调用者(FunBean)。ClassA 调用的是被注入进来的 FunBean,通常我们会为需要依赖注入的 对象留有 set 方法,在调用 callFoo 方法之前是需要先将 funBean 对象通过 setFunBean 方法设置进来的。
例如
public class ClassA {
private FunBean funBean = null;
public void setFunBean(FunBean funBean) {
this.funBean = funBean;
}
public void callFoo() {
this.funBean.foo();
}
}
public class FunBean {
...
}
严格意义上来说注入的形式分为两种,它们是 “构造方法注入” 和 “set 属性注入”。
我们经常听到有第三种注入方式叫 “接口注入”,其实它只是 “set 属性注入” 的一种接口 表现形式。
构造方法注入
这种方式是指被注入的对象通过构造方法传入:
例如
public class ClassA {
private FunBean funBean = null;
public ClassA(FunBean funBean) {
this.funBean = funBean;
}
public void callFoo() {
this.funBean.foo();
}
}
属性注入
是指被注入的对象通过其 get/set 读写属性方法注入进来:
例如
public class ClassA {
private FunBean funBean = null;
public void setFunBean(FunBean funBean) {
this.funBean = funBean;
}
public void callFoo() {
this.funBean.foo();
}
}
接口注入
是指通过某个接口的 set 属性方法来注入,大家可以看到其本质还是 属性注入。只不过调用者(ClassA),需要实现某个注入接口。
例如
public interface IClassA {
public void setFunBean(FunBean funBean);
}
public class ClassA implements IClassA {
private FunBean funBean = null;
public void setFunBean(FunBean funBean) {
this.funBean = funBean;
}
public void callFoo() {
this.funBean.foo();
}
}
上面我们讲解了什么是依赖注入,并且举例了一些依赖注入的表现形式。那么下一章我们来看看 Hasor 如何帮助我们你进行依赖注入。