大白話spring依賴注入

北漂程式設計師發表於2021-06-29

在前邊的文章中分享了spring如何實現屬性的注入,有註解和配置檔案兩種方式,通過這兩種方式可以實現spring中屬性的注入,具體配置可檢視《spring入門(一)【依賴注入】》,那麼spring是如何做到依賴注入的,今天不準備過多的引入原始碼,首先要搞清楚一些原理性的東西,然後再通過原始碼進行佐證。

java中的資料型別包括八種基本資料型別和引用型別,這兩類資料型別都可以作為屬性的資料型別,對於引用型別,包括Java自帶的一些類,比如String、List、Map等,這些都可以作為注入的目標型別,另外還包括自定義的引用型別,比如在A類中有一個資料型別為B的引用型別,那麼A、B都被spring管理,在生成A的例項的時候必定會把對B的引用進行注入。spring是如何進行注入的,有兩種不同的方式,分別是安照型別和名稱,所謂安裝型別就是在spring的IOC容器中尋找相同型別的bean的例項進行注入,所謂按照名稱就是在spring的IOC容器中按照bean的名稱查詢相同名稱的bean進行注入。

在spring的IOC容器中,所有的物件都叫做bean,bean是有生命週期的,一個bean從spring容器啟動開始到spring容器關閉,要經歷很多步驟。我們通過XML或者註解的形式配置的bean要被spring解析為beanDefinition物件,也就是spring可以識別的bean的元資訊,然後spring根據beanDefinition的資訊建立bean例項,這裡的bean不是普通意義上的java bean,而是spring中定義的一個例項的統稱,bean的建立過程又大體可描述為bean例項化前、bean例項化、屬性注入、bean初始化前、bean初始化、bean初始化後等過程,這些過程的執行都伴隨著相關的bean後置處理器的執行。

上面提到的beanDefinition相關的資訊完全可以在原始碼中體現,

在DefaultListableBeanFactory中有BeanDefinitionMap和beanDefinitionNames兩個變數,分別儲存的是BeanDefinition和BeandDefinitionName,佐證了前面提到的資訊。

那麼bean中屬性注入是在什麼地方那,下面看這樣一個方法,在AbstractAutowireCableBeanFactory中的createBean方法中,

有doCreateBean方法,該方法同樣在AbstractAutowireCapableBeanFactory類中,

有populateBean方法,該方法中便完成的是依賴注入相關的內容,具體的執行邏輯在下面的紅框中,

細心的讀者會發現這不是在迴圈BeanPostProcessor嗎,然後執行其中的postProcessProperties方法,沒錯是這樣的,看實現了postProcessProperties方法的類有哪些,

在這當中有兩個很重要的類分別是AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor,這兩個類分別完成的是註解@Autowired和@Resource的屬性注入功能,這兩個註解在《spring中BeanPostProcessor之四:AutowiredAnnotationBeanPostProcessor(01)和《spring中BeanPostProcessor之二:CommonAnnotationBeanPostProcessor(01)》中分別進行了介紹。其主要邏輯在各自的postProcessProperties方法中,以AutowiredAnnotationBeanPostProcessor為例,

主要的邏輯在metadata.inject方法中,

可以看到該方法從beanFactory中找到對應的value,其中找的具體過程在resolveDependency方法中,具體過程在doResolveDependency方法中,感興趣的讀者可以自己翻閱原始碼。

 

本篇文章重點在引導讀者去認識依賴注入的過程,依賴注入發生在bean建立過程中,在bean例項化之後進行屬性的注入,屬性的注入是通過bean後置處理器完成,針對不同的註解使用不同的後置處理器完成屬性注入,注入的過程肯定是在spring上下文中尋找匹配的bean的bean例項,最後通過反射的方式設定屬性值,

 

spring的原始碼很多,不可能一一列舉處理,僅提供一個大體的原始碼分析思路,望廣大讀者諒解,歡迎互相交流。

相關文章