大白話spring依賴注入


在前邊的文章中分享了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的源碼很多,不可能一一列舉處理,僅提供一個大體的源碼分析思路,望廣大讀者諒解,歡迎互相交流。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM