1. 程式人生 > >Spring IOC的實現

Spring IOC的實現

現在 () 引用 etc 其他 美的 init 理解 ray


來源:知乎 https://www.zhihu.com/question/21035417/answer/142858103

著作權歸作者所有。

Spring IOC的實現部分,主要分為三個部分:

第一步:

Resouce:首先我們需要獲取beanDefinition的資源,我們將通過Spring的resource接口獲得bean的資源,這一步也叫做bean資源的定位,下面是Spring內置的一些典型實現,當然,你也可以根據自己的需要實現自己的resource:

ClassPathResource可用來獲取類路徑下的資源文件。假設我們有一個資源文件test.txt在類路徑下,我們就可以通過給定對應資源文件在類路徑下的路徑path來獲取它,new ClassPathResource(“test.txt”)。

FileSystemResource可用來獲取文件系統裏面的資源。我們可以通過對應資源文件的文件路徑來構建一個FileSystemResource。FileSystemResource還可以往對應的資源文件裏面寫內容,當然前提是當前資源文件是可寫的,這可以通過其isWritable()方法來判斷。FileSystemResource對外開放了對應資源文件的輸出流,可以通過getOutputStream()方法獲取到。

UrlResource可用來代表URL對應的資源,它對URL做了一個簡單的封裝。通過給定一個URL地址,我們就能構建一個UrlResource。

ByteArrayResource

是針對於字節數組封裝的資源,它的構建需要一個字節數組。

ServletContextResource是針對於ServletContext封裝的資源,用於訪問ServletContext環境下的資源。ServletContextResource持有一個ServletContext的引用,其底層是通過ServletContext的getResource()方法和getResourceAsStream()方法來獲取資源的。

InputStreamResource是針對於輸入流封裝的資源,它的構建需要一個輸入流。

第二步:

第二步叫做bean Resource的解析:就是將我們獲取到的resource轉換成bean存在於Spring中的數據結構,也就是BeanDefinition,在我自己實現的Spring中,beanDefinition實現的比較簡單,主要有bean的作用域,持有bean的class對象,以及用一個String數組保存的它所依賴的bean的名字,現在也只能支持singleton和prototype兩種作用域;(Spring中beanDefinition的實現類並不多,大家可以去看下這部分的源代碼,弄懂了beanDefinition,IOC部分就明白一半了)

第三步:

在第二步bean資源的解析完成之後,我們需要將beanDefinition註冊到我們的工廠,用一個map集合進行保存;註冊完成之後,工廠的初始化也就完成了,接下來就是我們熟悉的通過getBean方法從容器中獲取我們所需要的bean了;getBean方法也正式觸發Spring依賴註入的起點,在這裏也是有兩個問題

1.如何保證Spring bean的創建順序,即被依賴的bean總是要先被完整的創建

2.當bean之間出現了循環依賴又該如何解決?

在這裏我用了組合模式,將Spring中的bean分為兩種,一種是依賴於其他bean的bean,一種是獨立的bean,它並不依賴於其他的bean,采用了遞歸的方式進行解決;(這部分說起來比較復雜,後面在貼代碼進行分析)

題主水平有限,對Spring的理解也很淺,如果講有錯誤的地方,歡迎指正

我自己實現的一個Spring地址:MySixGod/SpringImpl_v2.0 ,目前較好的解決了依賴的問題,但是依賴註入的方式單一,方法不靈活,對於屬性的命名,set方法的命名都有嚴格的要求,因為在此之前重心放在beanDefinition上,後續的話會實現別名接口,添加更多的註入方式,爭取能完成一個小而美的簡單版Spring吧

Spring IOC的實現