IOC和DI的理解 IOC和DI的理解

1.DI是什么

1.1DI—Dependency Injection,即"依赖注入":组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统提供一个灵活、可扩展的平台。

1.2依赖注入原理

1.2.1直接耦合方式

IOC和DI的理解
IOC和DI的理解

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依赖注入方式

IOC和DI的理解
IOC和DI的理解

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首先要明白以下几个问题:

  1. 谁控制谁
  2. 控制什么
  3. 什么是反转
  4. 哪些方面被反转

谁控制谁:在以前的编码中都是需要/依赖什么对象时程序员自己去创建——也就是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是一种实现方式。