1. 程式人生 > >3.Spring系列之IOC&DI

3.Spring系列之IOC&DI

java程序 xmlns 配置文件 string main 設計 instance 什麽是 資源獲取

一、什麽是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:光看概念也許不太容易理解,自己動手,會更明白 !

3.Spring系列之IOC&DI