這幾天正在複習Spring
的相關內容,同時想要對Spring
的實現原理作一些深刻的研究。今天看了看Spring
中IoC
的實現,找到了一篇很是詳細的博客,研究了一個下午,看完以後惟一的感覺就是——太複雜了。Spring
源碼中,類和接口的體系很是的複雜,同時方法的實現也是,方法調用感受無窮無盡,甚至相互調用,給我繞的暈暈的。應該是本身目前的技術水平還過低,項目經驗也不足,甚至對Spring
的運用都不夠熟悉,因此研究源碼對我來講可能仍是太早了。java
雖然對於Spring
的IoC
,我可能連十分之一都尚未弄懂,可是一個下午的研究也不是毫無收穫。這篇博客就來簡單講講我對IoC
的理解,以及Spring
中,IoC
最基本的實現流程。spring
在咱們使用傳統的編碼方式編寫代碼時,若是在類中須要引用另一個類的對象,咱們通常會直接在類中使用new
關鍵字,建立這樣一個對象。此時,使用這個對象的類,就與這個對象所對應的類產生了耦合性。c#
IoC
中文名稱爲控制反轉,它就是用來解決上述問題的一種設計思想,它能指導咱們設計出耦合性更低,更易於管理的代碼。傳統的程序,都是在須要使用的地方主動地建立對象,而IoC
的思想倒是將建立對象的工做交給IoC
容器去進行。咱們告訴IoC
容器,它須要建立那些對象,IoC
容器建立好這些對象,而後主動地將它們注入到須要使用的地方。此時,須要使用對象的那些類,並不主動地獲取對象,並且由IoC
容器爲它們分配,控制權在IoC
容器手上,這就是控制反轉。固然,IoC
容器並不僅是控制對象,能夠理解爲控制外部資源的獲取。oop
IoC
很好的體現了面向對象設計法則之一—— 好萊塢法則:「別找咱們,咱們找你」;即由IoC
容器幫對象找相應的依賴對象並注入,而不是由對象主動去找。post
DI
中文名稱爲依賴注入,它其實和IoC
是相同的概念,或者能夠理解爲它是IoC
的一種具體的實現方式。IoC
的概念可能比較模糊,控制反轉只是一種思想,可能僅僅只是停留在由其餘組件控制對象,而不是在使用的地方直接建立這一層面,可是具體如何實現並無指明。而DI
就是它的一種實現思路,由容器建立對象,並主動將對象注入到須要使用它的地方。2.1
中對IoC
的解釋,實際上更加偏向於DI
。學習
這一塊,我就簡單地說一說我今天下午在研究Spring
的IoC
源碼的過程當中,瞭解到的一些內容。首先,Spring
的IoC
容器,能夠簡單地理解爲就是BeanFactory
接口的一個實現類對象,好比Spring
的應用上下文接口ApplicationContext
就是繼承自BeanFactory
,而咱們使用較多的ClassPathXmlApplicationContext
就是ApplicationContext
的一個實現類。它們均可以理解爲是Spring
的IoC
容器,而BeanFactory
就是這個繼承體系中的最高層。下面我就以單例bean的建立,簡單地說一說Spring
的IoC
實現的一個過程,假設使用到的是ClassPathXmlApplicationContext
這個容器,解析的是xml
配置文件:編碼
xml
配置文件,將聲明在xml
文件中的bean
的配置信息提取出來,每個bean
的配置信息被封裝成一個BeanDefinitionHolder
對象。BeanDefinitionHolder
主要包含三個成員——BeanDefinition
對象,bean
的名稱(id
),以及bean
的別名。BeanDefinition
對象就是用來保存一個bean
的配置信息,好比bean
的做用域,bean
的類型,bean
的依賴,bean
的屬性......ConcurrentHashMap
對象,這個map
的key
是bean
的名稱,而value
則是BeanDefinition
對象的引用。容器將第一步中解析出的每個BeanDefinitionHolder
對象,它對應的bean
名稱,以及擁有的BeanDefinition
引用放入這個map
中。因此,這個map
保存了咱們在程序中聲明的全部的bean
的配置信息。bean
,遍歷第二步中的map
集合,獲取到bean
的名稱以及對應的BeanDefinition
對象,經過BeanDefinition
對象中的信息,判斷這個bean
有沒有定義爲延遲加載,若沒有,則須要如今就進行建立。在建立前,先經過BeanDefinition
中的配置信息,判斷此bean
有沒有depend-on
(依賴)其餘bean
,如有,則先建立當前bean
依賴的bean
(此處的depend-on
不是bean
的屬性,而是須要經過配置項進行配置的)。以後,則建立當前遍歷到的bean
。bean
在建立完成後,經過bean
的BeanDefinition
對象,獲取bean
須要注入值的屬性,而後爲屬性賦值,若屬性的值類型是其餘的bean
,則以上面相同的步驟,建立屬性對應的bean
;ConcurrentHashMap
,將建立好的單例bean
保存在其中。咱們在代碼中能夠經過容器的getBean
方法,傳入bean
的名稱或類型獲取單例bean
。容器會先去這個map
中查找,若map
中不存在,且這個bean
的配置在第2
步中存儲配置信息的map
中可以找到,則建立這個bean
,放入存儲bean
的map
中(由於bean
能夠配置延遲加載,即第一次獲取時加載); Spring
中,bean
最基本的兩種做用域就是singleton
(單例)和prototype
(多例),默認爲單例。以上過程是單例bean
的建立過程,若做用域爲prototype
,則每一次調用getBean
方法,都會建立一個新的bean
。順帶一提,建立bean
的方式是經過反射機制,這個大部分人應該都知道。prototype
以上內容是我根據本身的認識,對Spring
的IoC
作的一次簡單記錄,內容並不全面,由於我目前對它的理解也比較淺顯。在今天閱讀Spring
源碼的過程當中,我發現它真的比我想象中要複雜不少,或許是我水平有限,又或許是沒有掌握閱讀源碼的方法,讀起來真的很是吃力。總而言之,想要真正讀懂Spring
,我還須要不少的學習,但願從此可以儘快提高本身,早日將Spring
吃透。設計