Spring IOC 原理與IOC 容器實現
一. Spring IOC 原理
1. 概念
Spring 通過一個配置檔案描述 Bean 及 Bean 之間的依賴關係,利用 Java 語言的反射功能例項化Bean 並建立 Bean 之間的依賴關係。 Spring 的 IoC 容器在完成這些底層工作的基礎上,還提供了 Bean 例項快取、生命週期管理、 Bean 例項代理、事件釋出、資源裝載等高階服務。
2. Spring 容器高層檢視
Spring 啟動時讀取應用程式提供的 Bean 配置資訊,並在 Spring 容器中生成一份相應的 Bean 配置登入檔,然後根據這張登入檔例項化 Bean,裝配好 Bean 之間的依賴關係,為上層應用提供準備就緒的執行環境。其中 Bean 快取池為 HashMap 實現
3. IOC 容器實現
BeanFactory-框架基礎設施
BeanFactory 是 Spring 框架的基礎設施,面向 Spring 本身;ApplicationContext 面向使用Spring 框架的開發者,幾乎所有的應用場合我們都直接使用 ApplicationContext 而非底層的 BeanFactory。
BeanDefinitionRegistry 登入檔
(1). Spring 配置檔案中每一個節點元素在 Spring 容器裡都通過一個 BeanDefinition 物件表示,它描述了 Bean 的配置資訊。而 BeanDefinitionRegistry 介面提供了向容器手工註冊BeanDefinition 物件的方法。
BeanFactory 頂層介面
(2). 位於類結構樹的頂端 ,它最主要的方法就是 getBean(String beanName),該方法從容器中返回特定名稱的 Bean,BeanFactory 的功能通過其他的介面得到不斷擴充套件:
ListableBeanFactory
(3). 該介面定義了訪問容器中 Bean 基本資訊的若干方法,如檢視 Bean 的個數、獲取某一型別Bean 的配置名、檢視容器中是否包括某一 Bean 等方法;
HierarchicalBeanFactory 父子級聯
(4). 父子級聯 IoC 容器的介面,子容器可以通過介面方法訪問父容器; 通過HierarchicalBeanFactory 介面, Spring 的 IoC 容器可以建立父子層級關聯的容器體系,子容器可以訪問父容器中的 Bean,但父容器不能訪問子容器的 Bean。Spring 使用父子容器實現了很多功能,比如在 Spring MVC 中,展現層 Bean 位於一個子容器中,而業務層和持久層的 Bean 位於父容器中。這樣,展現層 Bean 就可以引用業務層和持久層的 Bean,而業務層和持久層的 Bean 則看不到展現層的 Bean。
ConfigurableBeanFactory
(5). 是一個重要的介面,增強了 IoC 容器的可定製性,它定義了設定類裝載器、屬性編輯器、容器初始化後置處理器等方法;
AutowireCapableBeanFactory 自動裝配
(6). 定義了將容器中的 Bean 按某種規則(如按名字匹配、按型別匹配等)進行自動裝配的方法;
SingletonBeanRegistry 執行期間註冊單例 Bean
(7). 定義了允許在執行期間向容器註冊單例項 Bean 的方法;對於單例項( singleton)的 Bean來說,BeanFactory 會快取 Bean 例項,所以第二次使用 getBean() 獲取 Bean 時將直接從IoC 容器的快取中獲取 Bean 例項。Spring 在 DefaultSingletonBeanRegistry 類中提供了一個用於快取單例項 Bean 的快取器,它是一個用 HashMap 實現的快取器,單例項的 Bean 以beanName 為鍵儲存在這個 HashMap 中。
依賴日誌框框
(8). 在初始化 BeanFactory 時,必須為其提供一種日誌框架,比如使用 Log4J, 即在類路徑下提供 Log4J 配置檔案,這樣啟動 Spring 容器才不會報錯。
二.ApplicationContext 面向開發應用
ApplicationContext 由 BeanFactory 派生而來,提供了更多面向實際應用的功能。
ApplicationContext 繼承了 HierarchicalBeanFactory 和 ListableBeanFactory 介面,在此基礎上,還通過多個其他的介面擴充套件了 BeanFactory 的功能:
1. ClassPathXmlApplicationContext:預設從類路徑載入配置檔案
2. FileSystemXmlApplicationContext:預設從檔案系統中裝載配置檔案
3. ApplicationEventPublisher:讓容器擁有釋出應用上下文事件的功能,包括容器啟動事件、關閉事件等。
4. MessageSource:為應用提供 i18n 國際化訊息訪問的功能;
5. ResourcePatternResolver : 所 有 ApplicationContext 實現類都實現了類似於PathMatchingResourcePatternResolver 的功能,可以通過帶字首的 Ant 風格的資原始檔路徑裝載 Spring 的配置檔案。
6. LifeCycle:該介面是 Spring 2.0 加入的,該介面提供了 start()和 stop()兩個方法,主要用於控制非同步處理過程。在具體使用時,該介面同時被 ApplicationContext 實現及具體Bean 實現, ApplicationContext 會將 start/stop 的資訊傳遞給容器中所有實現了該介面的 Bean,以達到管理和控制 JMX、任務排程等目的。
7. ConfigurableApplicationContext 擴充套件於 ApplicationContext,它新增加了兩個主要的方法: refresh()和 close(),讓 ApplicationContext 具有啟動、重新整理和關閉應用上下文的能力。在應用上下文關閉的情況下呼叫 refresh()即可啟動應用上下文,在已經啟動的狀態下,呼叫 refresh()則清除快取並重新裝載配置資訊,而呼叫 close()則可關閉應用上下文。
三.WebApplication 體系架構
WebApplicationContext 是專門為 Web 應用準備的,它允許從相對於 Web 根目錄的路徑中裝載配置檔案完成初始化工作。從 WebApplicationContext 中可以獲得ServletContext 的引用,整個 Web 應用上下文物件將作為屬性放置到 ServletContext中,以便 Web 應用環境可以訪問 Spring 應用上下文。