IOC和DI的理解
1.DI是什么
1.1DI—Dependency Injection,即"依赖注入":组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统提供一个灵活、可扩展的平台。
1.2依赖注入原理
1.2.1直接耦合方式
public class A {
B b = new B();
public void dosomething(){
b.dosomething();
}
}
public class B {
C c = new C();
public void dosomething(){
c.dosomething();
}
}
public class C {
public void dosomething(){
System.out.println("C : dosomething");
}
}
在这种常规写法中,当依赖关系越复杂时,所y依赖的类发生更改,所花费的维护代价就越大。当C类改变时,还要考虑到依赖自己的B类。当A类的调用变成D类时,也是要考虑到所依赖的B类的。
1.2.2依赖注入方式
import java.lang.reflect.Method;
public class A {
Object obj;
public A(Object obj) {
this.obj = obj;
}
public void dosomething() throws Exception {
Class<?> aClass = obj.getClass();
Method dosomething = aClass.getMethod("dosomething");
dosomething.invoke(obj);
}
}
import java.lang.reflect.Method;
public class B {
Object obj;
Method method;
public B(C c) {
obj = c;
}
public void dosomething() throws Exception {
Class<?> aClass = obj.getClass();
Method dosomething = aClass.getMethod("dosomething");
dosomething.invoke(obj);
}
}
public class C {
public void dosomething(){
System.out.println("C : dosomething");
}
}
//测试类调用
public class Test {
public static void main(String[] args) throws Exception {
A a = new A(new B(new C()));
a.dosomething();
}
}
//同样可以 A a = new A(new D());
//同样可以 A a = new A(new E());
//。。。。。
//即用即实例
用这种依赖注入的方式可以将A,B,C的依赖关系解除,也就是解耦。依赖注入的思想就是即用即实例,反转类与类之间的控制关系,实现由调用类A类控制后续的依赖关系,这样可以让B类随意的更改所需依赖和实例化的类(C类或D类),达到解耦的目的。和直接耦合方式相比,A类调用时,A类被依赖对象B和C的对象控制,这种依赖注入的方式就实现了控制反转。
2.IOC(控制反转)
2.1什么是IOC
IOC: Inversion Of Control,即“控制反转”,是一种设计思想,就是上文提到的控制反转。在Spring中意味着将对象交给IOC进行控制,而不是传统的在你的内部对象直接控制。要理解IOC首先要明白以下几个问题:
- 谁控制谁
- 控制什么
- 什么是反转
- 哪些方面被反转
谁控制谁:在以前的编码中都是需要/依赖什么对象时程序员自己去创建——也就是new,而有了IOC容器后由IOC控制。也就是所有的类都会在IOC容器中进行登记,当需要某个对象时,由IOC提供。总之,就是以前是程序员控制对象,有了IOC容器后由IOC控制对象。
控制什么:控制实现过程中所依赖的对象,如上文的例子,A依赖于B,B依赖于C,当A调用时,IOC会将A依赖的B的对象注入,B依赖的C的对象注入。(底层实现原理并不是上文中的例子那样简单)
什么是反转:没有IOC容器时,都是程序员在对象中主动创建依赖的对象。有了IOC容器以后,依赖的对象是有IOC容器创建后注入到对象中,由主动创建变成了被动接受,这是反转。
哪些方面被反转:依赖对象的方式。
2.2IOC能做什么
IoC 不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是 松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。
其实IOC对编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化。应用程序原本是老大,需要什么对象就创建什么对象,而引入IOC容器后,应用程序就变成被动了,所依赖的对象不再由自己创建,而是由IOC容器进行注入,应用程序被动接受。
2.3IOC和DI的关系
IOC和DI并不是一个概念,更确切应该说IOC是一种思想,而DI是一种实现方式。