3.Spring系列之IOC&DI

一、什么是IOC?


1.概念

IOC—Inversion of Control,即“控制反转”,不是新的技术,而是一种设计思想。Java开发中,IOC意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制;

2.谁控制谁,控制什么

传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IOC是有专门一个容器来创建这些对象,即由IOC容器来控制对象的创建;注意:是IOC 容器控制了对象;主要控制了外部资源获取(不只是对象包括比如文件等)。

3.为何是反转,哪些方面反转了

有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;

  为何是反转:因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;

  什么反转了:依赖对象的获取被反转了。

4.总结:

说白了就是对象不需要你去new,而是交给IOC帮你创建对象,并且帮助我们建立好了类与类之间的关联关系,我们需要时再去获取。

 

二、什么是DI?


实际上DI和IOC是同一个概念,因为在ApplicationContext.xml配置文件中bean和bean之间通过ref来维护的时候是相互依赖的,所以又叫做依赖注入。也就是控制反转。

 

三、实例


 我们通过一个实例加深Spring IOC&DI的理解:

1.传统的Java程序,这里建立两个实体的关联关系:

public class A{
   public void show(){
      System.out.println("A show()...");
   }
}
public class B{
   private A a;
   public void show(A a){
      a.show();
   }
}
public class Main{
   public static void main(String[] args){
      A a = new A();
      B b = new B();
      b.show(a);
   }
}

从上方代码看出,我们如果使用组合,那么使用起来必然是比较麻烦,不仅需要创建B对象,而且还需要创建A对象,然后再将A对象传给B的方法,再调用show方法。

然而,使用spring后,只需要在IOC容器中配置两个的关联,在测试方法中,直接B b = new B();这时A自动就被创建,并且包含在B中,而无需我们再去创建A对象,节省了很多操作,我们来看看创建了IOC容器对象后,IOC容器帮我们做了哪些工作:

首先创建两个Bean,分别是Parent和Child:

public class Parent {

    private Child child;
    
    public void setChild(Child child) {
        this.child = child;
    }

    public Child getChild() {
        return child;
    }

    public Parent(){
        System.out.println("Parent Constructor...");
    }
}
public class Child {

    public Child(){
        System.out.println("Child Constructor...");
    }
}

接着,在applicationContext.xml中配置以上两个Bean以及引用关系:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="child" class="com.spring.model.Child"></bean>
    
    <bean id="parent" class="com.spring.model.Parent">
        <property name="child" ref="child"></property>
    </bean>
</beans>

最后,测试程序:

public class Main {

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    }
}

执行后,输出:

Child Constructor...
Parent Constructor...

说明:只要Bean配置到IOC容器中,IOC容器会通过配置在其里面的Bean的全限定名以反射的方式通过无参构造器创建Bean的实例。

由于IOC容器内已配置关联关系,所以我们在测试程序中获取Bean:

public class Main {

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        Parent parent = ctx.getBean(Parent.class);
        System.out.println("parent=" + parent);
        System.out.println("child=" + parent.getChild());
    }
}

执行后,输出结果:

Child Constructor...
Parent Constructor...
parent=com.spring.model.Parent@6f7fd0e6
child=com.spring.model.Child@47c62251

 

四、总结


Bean实例化和Bean与Bean之间的依赖关系交给IOC容器帮我们实例化,我们需要时再去获取。

PS:光看概念也许不太容易理解,自己动手,会更明白 !

 

posted @ 2018-04-06 09:39  飘飘来来荡荡去去  阅读(174)  评论(0编辑  收藏  举报