【Spring 從0開始】IOC 容器、底層原理
一、什麼是IOC
IOC 是控制反轉,把物件建立和物件之間的呼叫過程,交給 Spring 來管理,可以使程式碼耦合度降低。
在上篇中,使用了xml管理物件的建立,其實這就是IOC的實現。
二、IOC底層原理
IOC的實現主要用到了3種技術:工廠模式、XML解析、反射。
1. 工廠模式介紹
原始狀態
用圖示表示下,初始的物件呼叫的樣子。比如我在 UserService 類中想呼叫 UserDao 類下的 add() 方法,需要 new 一個 UserDao 的物件。
但是這種呼叫方法會讓 UserService 和 UserDao 這2個類耦合過於緊密。比如,當 UserDao 路徑變化了,UserService 裡也要跟著變。
本著高內聚、低耦合,我們還需要進一步降低程式的耦合。
工廠模式
於是,為了更好的解耦合,出現了工廠模式。加入了工廠之後,上面的物件呼叫關係就變成了這樣:
通過 UserFactory 這個工廠類,降低 UserService 和 UserDao 這2個類的耦合。
但是,UserFactory 這個工廠也是一個類,這個類與其它的耦合也仍然是存在,所以這仍然不是最終方案。
若再進一步的降低耦合,則是用到 IOC 的方案了。
XML解析用來獲取或操作檔案裡的內容。而反射則是通過得到類的位元組碼檔案,也就是寫的java檔案編譯後的class檔案,然後操作類中的所有內容。
2. IOC 執行過程
第一步
通過 XML 檔案,進行物件的配置。比如我在檔案裡配置了一個 user 物件。
第二步
有了 XML 檔案後,IOC就可以解析檔案獲取物件,然後建立工廠類,進行物件的返回了。
圖示程式碼僅示意用:
- 通過解析XML,拿到class屬性的值。
- 通過反射,建立物件。
- 建立物件,返回。
同樣是用到工廠模式,不過通過IOC的方式,進一步降低了耦合度。
因為,這時候就算 User 類的路徑變了,不是這個 "com.pingguo.spring5.User"
,那麼只需要改XML檔案即可,不需要改其他的程式碼。
三、IOC 介面
IOC 容器其實指得就是物件工廠,而在 spring 裡,提供了兩種實現 IOC 容器的方式(介面)。
在上篇文章的測試程式碼中,我把 ApplicationContext 替換成 BeanFactory 一樣可以正常執行。
1. BeanFactory
Spring 內部使用的介面,一般不提供給我們開發人員使用。它的特點是:
- 載入配置檔案的時候不會建立物件,當使用物件的時候才會建立物件。
2. ApplicationContext
BeanFactory 是 ApplicationContext 的子介面,提供了更多、更強大的功能,這個介面是面向我們開發人員使用的。
如果你使用 idea 編輯器,可以 Ctrl+左擊
BeanFactory ,然後點選 BeanFactory 前面的 ↓ 箭頭看到實現的父介面。
它的特點與 BeanFactory 相反:
- 載入配置檔案的時候,就會建立配置的物件。
3. ApplicationContext 的兩個主要實現類
可以單擊 ApplicationContext,按 Ctrl+H
,檢視結構。
- ClassPathXmlApplicationContext:在上篇的示例程式碼裡,使用的就是這個類。它的特點是,這裡直接寫 src 下的xml檔案路徑即可。
- FileSystemXmlApplicationContext:這裡用的是檔案在磁盤裡的全路徑,比如
D:\IdeaProjects\spring5_demo\src\bean1.xml
。
4. BeanFactory 與 ApplicationContext 誰更好?
乍一看感覺 BeanFactory 更好一些,因為我需要用的時候再建立,節省資源。
不過,站在實際生產的角度,spring通常是應用於web專案,比如結合tomcat。那麼當tomcat的啟動的時候,我們更希望把這些耗時耗資源的操作,都在專案啟動的時候處理,會更合適。