目錄
1 .IOC 概述
2 .IOC容器的設計
3 .Spring IOC容器的定義和初始化
4 .Beand的生命週期
5 .IOC總結
IOC 概述
IOC(控制反轉):也是一個發佈Bean的容器
控制反轉是個很抽象的東西,那就得了解誰控制誰?誰被反轉了?
控制:傳統Java SE程序設計,我們直接在對象內部通過new進行創建對象,是程序主動去創建依賴對象;而IoC是有專門一個容器來創建這些對象,即由Ioc容器來控制對 象的創建;誰控制誰?當然是IoC 容器控制了對象;控制什麼?那就是主要控制了外部資源獲取(不只是對象包括比如文件等)
反轉:傳統應用程序是由我們自己在對象中主動控制去直接獲取依賴對象,也就是正轉;而反轉則是由容器來幫忙創建及注入依賴對象。
爲什麼是反轉,而不是正轉?因爲由容器幫我們查找及注入依賴對象,對象只是被動的接受依賴對象,所以是反轉。對象的獲取被反轉了。
就比如:你做開發,負責商品交易模塊的,但是交易涉及到財務模塊,而你並不瞭解財務模塊,所以也不能輕易處理,這時你期望的是:
- 熟悉財務流程
- 接口邏輯儘量簡單,只需要調用就行
- 通過簡單描述就能獲取到接口實例,且描述應該儘量簡單
現實的實例和開發思想(IOC)也是很相似的:
財務的接口對象並不是自己創建的,而是財務部門創建的,但是也達到了你的需要。而在潛意識中你覺得你對象應該由你主動創建,但事實上並不是你真正的需要,因爲也許你對你需要的業務一點都不精通,這個時候把創建對象的主動權交給別人,這就是控制反轉的概念。
控制反轉的概念:控制反轉是一種通過描述(在java中可以是XML或者註解)並通過第三方去產生或獲取特定的對象的方式。
而在Spring實例中實現控制反轉的是IOC容器,其實現方式是依賴注入(DI)。Spring就會提供IOC容器來管理對應的資源。就比如:財務方面的接口模塊開發已經完成,只需要把財務模塊發佈到IOC容器中,然後將交易模塊也發佈IOC容器中,使用XML或者註解,配置接口之間依賴注入的關係,Spring就會將其進行管理。而測試也只需要在IOC容器中獲取財務模塊的內容就行。
這就是一種控制反轉的理念。它最大的理念就是降低對象之間的耦合,對於系統中的一些類,具體如何實現並不需要去理解,只需要它有什麼用就可以的。就是對象的產生依賴IOC容器,而不是開發者主動的行爲。主動創建對象的模式,責任歸於開發者。被動創建的模式下,責任歸於IOC容器,這樣被動的模式,我們就可以理解爲對象被控制反轉了。
IOC容器的設計
Spring IOC容器的設計主要是基於BeanFactory和ApplicationContext兩個接口,IOC容器主要接口如圖:
從這張圖可以看出來BeanFactory爲於設計的底層,ApplicationContext是其中的高級接口。
BeanFactory類的主要方法就是一些getBean的方法,參數可以是擴展接口也可以是父類,但是接口底下有多個實現類(類有多個子類)的時候,這時通過父類就無法獲取到準確的實例,因爲容器無法判斷具體的實現類。
還有isSingleton方法:用於判斷是否單例。如果爲真,就是該Bean在IOC容器中是作爲唯一實例存在的。
isPrototype反法和isSingleton方法相反,判斷爲真的時候,意思是當你從容器中獲取Bean,容器就會爲你生成一個新的實力。
默認情況下:Spring會爲Bean創建一個單例,就是默認isSingleton返回爲true,isPrototype返回爲false。
Spring IOC容器的定義和初始化
Bean的定義:
- Resoure定位:
IOC容器根據開發者的配置進行資源定位 - BeanDefinition載入:
這個時候是將Resource定位到的資源文件的信息保存到Bean定義(BeanDefinition)中,此時並不會創建Bean實例 - BeanDefinition註冊:
將載入的信息,發佈到IOC容器中,注意,此時任舊並不會創建Bean實例
Bean的初始化:
Spring Bean有個配置選項 – lazy-init,默認值爲default,實際值爲false,就是IOC容器默認會自動初始化Bean。如果設置爲true的時候,就只有當我們使用IOC容器的getBean方法獲取的時候,纔會進行Bean的初始化。
Beand的生命週期
- 定義
- 初始化
- 依賴注入
- setBeanName
如果實現了接口BeanNameAware接口的setBeanName方法,那麼它就會調用這個方法 - setBeanFactory
如果Bean實現了BeanFactoryWare接口的setBeanFactory方法,那麼它就會調用這個方法 - setApplicationContext
如果Bean實現了ApplicationContext接口的setApplicationContext方法,且IOC容器也必須是一個ApplicationContext接口的實現類,那麼纔會調用這個方法,否則不調用的。 - postProcessBeforeInitialization
如果Bean實現了BeanPostProcess接口的postProcessBeforeInitialization方法,那麼它就會調用這個方法 - afterPropertiesSet
如果Bean實現了BeanFactoryPostProcess接口的afterPropertiesSet方法,那麼它就會調用這個方法 - 自定義初始化方法
如果自定義初始化方法,就調用已定義的初始化方法 - postProcessAfterInitialization
如果Bean實現了BeanPostProcess接口的postProcessAfterInitialization方法,完成了這些調用,這個時候Bean就完成了初始化,那麼Bean就生存在IOC容器中了,使用者就可以從中獲取Bean的事物 - 生存期
- destroy
如果Bean實現了DisposableBean接口的destroy方法,那麼它就會調用這個方法 - 自定義銷燬方法
如果自定義銷燬方法,就調用自定義方法
IOC總結
對於IOC控制反轉理解接口現實實例,會更好理解,控制反轉只是一種思想模式,只是比較抽象帶來理解困難,將抽象的事物現實化,就更加清晰。
IOC容器就是爲了管理Bean而服務的。
注意掌握BeanFactory所定義的基本方法,因爲BeanFactory是IOC的最爲基礎的底層設計
Bean的生命週期,注意需要通過哪些生命週期接口和方法實現的,它允許我們自定義初始化和銷燬。