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:光看概念也許不太容易理解,自己動手,會更明白 !
3.Spring系列之IOC&DI