本文為作者搜集的Spring關於IoC/DI相關知識的記錄整理筆記。介紹了IoC(控制反轉)是一種設計原則,用於降低代碼的耦合度。介紹了IoC是通過BeanDefinition來定義Bean對象及其關係,用BeanFactory來管理Bean的生命周期。 ...
一、摘要
本文為作者搜集的Spring關於IoC/DI相關知識的記錄整理筆記。介紹了IoC(控制反轉)是一種設計原則,用於降低代碼的耦合度。介紹了IoC是通過BeanDefinition來定義Bean對象及其關係,用BeanFactory來管理Bean的生命周期。
二、什麼是IoC/DI
IoC,全稱Inversion of Control,控制反轉,是面向對象編程中的一種設計原則,這種設計可以減低電腦代碼之間的耦合度。 通過IoC,對象在創建的時候,就不需要調用方用new的方式來創建實例,而是由外部系統創建對象實例,並把對象引用傳遞給調用方。 IoC的實現方式有DI(Dependency Injection,依賴註入)和DL(Dependency Lookup,依賴查找),其中在Spring中DI就是由Spring框架負責創建實例,並把註入到調用方對象中,如圖1。 (圖1、IoC示意圖)三、Spring IoC體繫結構
IoC容器用來完成對象的創建和依賴管理,對象和對象關係可以使用XML文件、註解來描述。 Spring框架中,對象的創建可以看BeanFactory,對象及其關係的定義可以看BeanDefinition。1、BeanFactory
(圖2、BeanFactory類繼承圖) 這是一個工廠模式,BeanFactory對IoC基本容器的基本行為作了定義,但不負責實現。Spring提供了若幹個IoC容器的,有:XmlBeanFactory、ClassPathXmlApplicationContext BeanFactory定義了Spring Bean獲取及其相關的方法,如下: getBean – 根據Bean名稱或類對象獲取Bean實例 getAliases – 根據Bean名稱獲取別名列表 getType – 根據Bean名稱獲取Bean類對象 isPrototype – 判斷Bean是否屬於原型模式 isSingleton – 判斷Bean是否屬於單例模式 isTypeMatch – 判斷類對象是否與Bean類型匹配上2、BeanDefinition
BeanDefinition是用來定義Bean的一個介面,是Bean對象的抽象數據結構,其包括了構造器參數、屬性參數以及其它具體的參數。四、IoC容器的初始化及Bean的作用域及其生命周期
1、IoC容器的初始化
三個基本過程:資源定位、載入、註冊; (1)Resource定位:Bean的定義文件定位 (2)載入:將Resource定位好的資源載入到BeanDefinition (3)註冊:將BeanDefinition註冊到容器中 Spring會將資源定位成為Resource對象,BeanDefinition會讀取Resource形成BeanDefinition對象。最終BeanDefinition會和beanName、Alias一同封裝到BeanDefinitionHolder類中,註冊到BeanFactory的實現類(DefaultListtableBeanFactory.beanDefinitionMap)中。 Spring容器會根據註冊的BeanDefinition信息將Bean進行實例化。2、Bean的生命周期
這裡講Bean的生命周期,瞭解Bean的生命周期,可以根據自己的需要,在不同階段做一些定製處理。 Bean的生命周期線索:實例化、初始化、使用、銷毀 示意圖: (圖3、Bean的生命周期) 具體如下: — 實例化 — (1)Bean實例化 — 初始化 —(各種Aware介面) (2)屬性註入 (3)設置Bean的名稱(BeanNameAware.setBeanFactory()) 描述:如果Bean實現了BeanNameAware介面,工廠會調用該方法傳遞Bean的ID (4)設置BeanFactory?(BeanFactoryAware.setBeanFactory) 描述:如果Bean實現了BeanFactoryAware介面,工廠會調用該方法傳遞工廠本身 (5)調用BeanPostProcessor前置處理方法(BeanPostProcessor.postProcessBeforeInitialization()) 描述:如果有BeanPostProcessor和該Bean關聯(註意是關聯,即不需要該Bean去實現BeanPostProcessor介面),則postProcessBeforeInitialization會被調用 用途:1、進行AB測試時,可以在此處做路由;2、進行密文轉明文處理; (6)調用屬性設置後置處理方法(InitializingBean.afterPropertiesSet()) 描述:如果Bean實現了InitializingBean介面,工廠會執行afterPropertiesSet方法內容 (7)調用定製的初始化方法(init-method屬性) 描述:執行Bean的init-method屬性定義的方法 (8)調用BeanPostProcessor後置處理方法(BeanPostProcessor.postProcessAfterInitialization()) 描述:如果有BeanPostProcessor和該Bean關聯(同(5)),則postProcessAfterInitialization會被調用 — 使用 — (9)這一步Bean已經可以被使用了,如果容器被關閉,則繼續下一步 — 銷毀 — (10)調用方法DisposableBean.destroy() 描述:如果Bean實現了DisposableBean介面,則destroy方法會被調用 (11)調用定製的銷毀方法(destroy-method) 描述:執行Bean的destroy-method屬性定義的方法3、Bean的作用域
Bean由IoC容器進行管理的對象,每個作用域的總結如下:類別 | 說明 | 應用 |
singleton | 預設為單例模式,在Spring IoC容器中僅存在一個Bean實例。 | 無狀態Bean |
prototype | 每次從容器中調用Bean,都返回一個新的實例。 | 有狀態Bean |
request | 每次Http請求都會創建一個新的Bean(僅限WebApplicationContext環境) | 創建的Bean僅當前Http請求有效。 |
session | Http Session共用一個Bean(僅限WebApplicationContext環境) | 創建的Bean僅當前Http Session有效。 |
globalSession | 一般用於Portlet應用環境(僅限WebApplicationContext環境) | 不知道有什麼鬼用 |