您好,登錄后才能下訂單哦!
這篇文章主要講解了“java Spring源碼分析”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“java Spring源碼分析”吧!
Spring 里面最重要的特性就是 Ioc,可能你還會說aop。其實aop的實現也是基于 ioc。Ioc (Inversion of Control),即“控制反轉”,不是什么技術,而是一種設計思想。在Java開發中,Ioc意味著將你設計好的對象交給容器控制,而不是傳統的在你的對象內部直接控制。
關于 Spring IOC 源碼分析的文章網上很多,現在我就來另辟蹊徑。Spring Ioc 的對象扭轉以及 涉及到的核心接口來分析一下它的源碼實現。
Resource -> BeanDefinition -> BeanWrapper -> Object
1 Resource
Resouce 其實是一個接口,代表的是資源,在計算機里面從一個地方移動到另外一個地方所需要的東西就是數據流,所以 Resource 實現了 InputStreamSource 接口,通過 InputStreamSource 接口可以獲取到 Inputstream,這樣就可以讀取不同的 Bean 定義了。
public interface InputStreamSource { InputStream getInputStream() throws IOException; }
Spring 可以定義不同類型的 bean,最后都可以封裝成 Resource 通過 IO 流進行讀取。 Spring 可以定義類型的 bean 對象:
XML:這是 Spring 最開始定義 bean 的形式
Annotation :由于通過 XML 定義 bean 的繁瑣,Spring 進行了改進可以通過 @Component 以及基于它的注解來定義 bean。例如:@Service,@Controller等等,它們都可以定義 bean ,只不過語義更加明確。
Class:通過 @Configuration 與 @Bean 注解定義,@Configuration 代理 xml 資源文件,而 @Bean 代替 <bean> 標簽。
Properties/yml:通過 @EnableConfigurationProperties 與 @ConfigurationProperties 來定義 bean。這種形式在 Spring boot 自動注入里面大量使用。
望文生義,很顯示這個是 Bean 對象的定義。 Spring 通過不同形式來定義 bean,最終會把這些定義轉化成 BeanDefinition 保存在 Spring 容器當中進行依賴注入。下面我們來看一下 BeanDefinition 的接口定義。
這個接口的定義很復雜但是,對于初始理解 spring ioc,只需要關心兩個方法。
getConstructorArgumentValues:獲取構造器注入定義的參數。
getPropertyValues:獲取 setter 注入定義的參數。
所以 Spring 支持構造器注入與 setter 依賴注入。
其實什么是依賴注入,簡單來說就是 Spring 幫我們創建對象。把創建對象寫死在 Java 文件變成了通過不同的 Spring 配置可以注入不同的值。創建對象的職責由 Java 文件變成了 Spring 配置文件。
下面我就問一個簡單的問題,如何創建對象。可能大家呵呵一笑,創建對象這還不簡單。
其實 Spring 也是這樣來創建對象的,不信講看 : (入口方法 BeanFactory#getBean)
AbstractAutowireCapableBeanFactory#createBeanInstance() :通過反射 Constructor 調用配置的無參或者有參來創建對象實例。通過 BeanDefinition#getConstructorArgumentValues 獲取,并返回 BeanWrapper 對象。
AbstractAutowireCapableBeanFactory#populateBean():,獲取到定義的 bean 生成的所有的定義的setter注入的屬性(BeanDefinition#getPropertyValues),然后遍歷些這些屬性,通過內省獲取到對象所有的 屬性描述器(PropertyDescriptor),獲取到,屬性的 PropertyDescriptor#getWriteMethod 方法,也就是 setter 方法,依賴注入值。如果是普通屬性或者一些復雜對象,比如普通屬性 String, int, long 或者 classpath:*轉換為 Resource 復雜對象等等,直接注入即可;對于引用類型對象,繼續依賴注入直到所有的屬性是普通屬性為止。
AbstractAutowireCapableBeanFactory#initializeBean():調用 Spring 自定義的初始化方法比如:BeanPostProcessor 擴展以及 init-method。
實例化對象返回 BeanWrapper,其實是為了依賴注入服務也就是上面的第二步。 這個接口的功能還是很復雜的,它繼承了 4 個接口。
TypeConverter
PropertyEditorRegistry
PropertyAccessor
ConfigurablePropertyAccessor
下面就來分別介紹一下這些接口的功能。
下面就是這個接口的定義。
它的作用就是自動類型轉換,因為 Spring 作得太無感知了。你也許還沒有感覺到它的存在。沒關系,我提示一下你應該就會明白。比如,聲明一個用戶對象這個對象既有 String 類型的名稱,又有 Int 類型的年齡。 Spring 怎么知道屬性的類型呢?這個就是 Spring 的自動類型轉換。關于 Spring 的自動類型轉換 我在之前就已經分析過了。
這個接口主要的作用是注冊屬性修改器(PropertyEditor),這個是 Java 內省里面的機制。
PropertyAccessor 這個接口是判斷對象中的某個屬性是否可讀/可寫,并且可以定入或者讀取某個屬性的值。從這個接口定義我們可以看出,它的使用其實就是真正用來依賴注入的。然后調用屬性操作的寫入操作,完全依賴注入。
這個接口的功能和 PropertyEditorRegistry 接口一樣,只不過后者是通過 java 內省來進行類型自動轉換,而 ConfigurablePropertyAccessor 接口是通過 Spring 自己定義的 org.springframework.core.convert.ConversionService 來作類型轉換類型轉換。在 Spring 中默認使用的是 DefaultConversionService 來作自動類型轉換支持,并且內部還添加了很多默認的類型轉換。
關于 Spring 的自動類型轉換 我在之前就已經分析過了。和 java 內省的原理是一樣的。
這個接口就挺簡單了,通過實現了上面的幾個接口具有了依賴注入、類型轉換注冊(java 內省或者 Spring 自定義的 自動類型轉換)。然后這個接口的主要的作用就是通過調用 getWrappedInstance 方法獲取到當前實例對象,提供給屬性的 writer 方法進行依賴注入。
writeMethod.invoke(getWrappedInstance(), value);
感謝各位的閱讀,以上就是“java Spring源碼分析”的內容了,經過本文的學習后,相信大家對java Spring源碼分析這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。