Spring學習筆記:IOC容器

理論基礎

IoC是什麼

Ioc—Inversion of Control,即“控制反轉”,它不是什麼技術,而是一種設計思想。在 Java 開發中, Ioc 意味着將你設計好的對象交給容器控制,而不是傳統的在你的對象內部直接控制。如何理解好 Ioc 呢?理解好 Ioc 的關鍵是要明確“誰控制誰,控制什麼,爲何是反轉(有反轉就應該有正轉了),哪些方面反轉了”,那我們來深入分析一下:

誰控制誰,控制什麼:傳統 Java SE 程序設計,我們直接在對象內部通過 new 進行創建對象,是程序主動去創建依賴對象;而 IoC 是有專門一個容器來創建這些對象,即由 IoC 容器來控制對象的創建;誰控制誰?當然是 IoC 容器控制了對象;控制什麼?那就是主要控制了外部資源獲取(不只是對象包括比如文件等)。

爲何是反轉,哪些方面反轉了:有反轉就有正轉,傳統應用程序是由我們自己在對象中主動控制去直接獲取依賴對象,也就是正轉;而反轉則是由容器來幫忙創建及注入依賴對象;爲何是反轉?因爲由容器幫我們查找及注入依賴對象,對象只是被動的接受依賴對象,所以是反轉;哪些方面反轉了?依賴對象的獲取被反轉了。

用圖例說明一下,傳統程序設計都是主動去創建相關對象然後再組合起來:

這裏寫圖片描述
當有了 IoC/DI 的容器後,在客戶端類中不再主動去創建這些對象了,如圖:
這裏寫圖片描述

IoC能做什麼

IoC 不是一種技術,只是一種思想,一個重要的面向對象編程的法則,它能指導我們如何設計出松耦合、更優良的程序。傳統應用程序都是由我們在類內部主動創建依賴對象,從而導致類與類之間高耦合,難於測試;有了IoC容器後,把創建和查找依賴對象的控制權交給了容器,由容器進行注入組合對象,所以對象與對象之間是鬆散耦合,這樣也方便測試,利於功能複用,更重要的是使得程序的整個體系結構變得非常靈活。

其實 IoC 對編程帶來的最大改變不是從代碼上,而是從思想上,發生了“主從換位”的變化。應用程序原本是老大,要獲取什麼資源都是主動出擊,但是在 IoC/DI 思想中,應用程序就變成被動的了,被動的等待 IoC 容器來創建並注入它所需要的資源了。

IoC 很好的體現了面向對象設計法則之一的好萊塢法則:“別找我們,我們找你”;即由 IoC 容器幫對象找相應的依賴對象並注入,而不是由對象主動去找。

IoC和DI

  • DI—Dependency Injection,即“依賴注入”:是組件之間依賴關係由容器在運行期決定,形象的說,即由容器動態的將某個依賴關係注入到組件之中。依賴注入的目的並非爲軟件系統帶來更多功能,而是爲了提升組件重用的頻率,併爲系統搭建一個靈活、可擴展的平臺。通過依賴注入機制,我們只需要通過簡單的配置,而無需任何代碼就可指定目標需要的資源,完成自身的業務邏輯,而不需要關心具體的資源來自何處,由誰實現。

  • 理解 DI 的關鍵是:“誰依賴誰,爲什麼需要依賴,誰注入誰,注入了什麼”,那我們來深入分析一下:

  • 誰依賴於誰:當然是某個容器管理對象依賴於 IoC 容器;“被注入對象的對象”依賴於“依賴對象”;
    爲什麼需要依賴:容器管理對象需要 IoC 容器來提供對象需要的外部資源;
    誰注入誰:很明顯是 IoC 容器注入某個對象,也就是注入“依賴對象”;
    注入了什麼:就是注入某個對象所需要的外部資源(包括對象、資源、常量數據)。
    IoC 和 DI 由什麼關係呢?其實它們是同一個概念的不同角度描述,由於控制反轉概念比較含糊(可能只是理解爲容器控制對象這一個層面,很難讓人想到誰來維護對象關係),所以 2004 年大師級人物 Martin Fowler 又給出了一個新的名字:“依賴注入”,相對 IoC 而言,“依賴注入”明確描述了“被注入對象依賴 IoC 容器配置依賴對象”。

IoC 容器

IoC 容器就是具有依賴注入功能的容器,IoC 容器負責實例化、定位、配置應用程序中的對象及建立這些對象間的依賴。應用程序無需直接在代碼中 new 相關的對象,應用程序由 IoC 容器進行組裝。在 Spring 中 BeanFactory 是 IoC 容器的實際代表者。

Spring IoC 容器如何知道哪些是它管理的對象呢?

這就需要配置文件,Spring IoC 容器通過讀取配置文件中的配置元數據,通過元數據對應用中的各個對象進行實例化及裝配。一般使用基於 xml 配置文件進行配置元數據,而且 Spring 與配置文件完全解耦的,可以使用其他任何可能的方式進行配置元數據,比如註解、基於 java 文件的、基於屬性文件的配置都可以。

在 Spring Ioc 容器的代表就是 org.springframework.beans 包中的 BeanFactory 接口, BeanFactory 接口提供了 IoC 容器最基本功能;而 org.springframework.context 包下的 ApplicationContext 接口擴展了 BeanFactory ,還提供了與Spring AOP 集成、國際化處理、事件傳播及提供不同層次的 context 實現 (如針對 web 應用的 WebApplicationContext )。簡單說, BeanFactory 提供了 IoC 容器最基本功能,而 ApplicationContext 則增加了更多支持企業級功能支持。 ApplicationContext 完全繼承 BeanFactory ,因而 BeanFactory 所具有的語義也適用於 ApplicationContext。

  • XmlBeanFactory: BeanFactory實現,提供基本的IoC容器功能,可以從classpath
    或文件系統獲取資源
    1.從文件系統獲取資源
File file =new File("fileSystemConfig.xml");
Resource resource = new FileSystemResource(files);
BeanFactory benaFactory = new XmlBeanFactory(resource);

2.從classpath獲取資源

Resource resource = new ClassPathResource("classpath.xml");
BeanFactory beanFactory = new XmlFactory(resource);
  • ClassPathXmlApplicationContext: ApplicationContext實現,從classpath獲取配置文件
BeanFactory beanFactory= new ClassPathXmlApplicationContext("classpath.xml");
  • FileSystemXmlApplicationContext: ApplicationContext實現,從文件系統中獲取資源
BeanFactory beanFactory = new FileSystemXmlApplicationContext("fileSystemConfig.xml");

Spring Ioc容器給Bean屬性注入value

Spring 中,通常有 3 種方法給 Bean 的屬性注入 value 。
1. 一般方法

<bean id="" class="">
    <property name="">
        <value></value>
    </property>
</bean>
  1. 縮寫方法
<bean id="" class="">
    <property name="" value=""/>
</bean>
  1. p schema方法
    在xml配置文件的beans標籤中添加
    xmlns:p=”http://www.springframework.org/schema/p

然後就可以使用p標籤代替property標籤

<bean id="" class="" p:屬性名="屬性值">
</bean>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章