主題
學習分享記錄一下Spring是怎么注入@Autowired標注的bean的.
配置BeanPostProcessor
傳統的spring項目中配置基本是通過XML來操作的.在XML中經常會有這種配置
<context:annotation-config/> 或者 <context:component-scan>
或者類似的配置.這些配置是開啟@Autowired等注解的關鍵. 先看看他們做了什么.
解析標簽
XML中這些特殊的namespace基本都是由XXXNameSpaceHandler來做解析的
比如AOPNamspaceHandler負責解析 <aop:aspectj-autoproxy /> 等命名空間
類似的context:XXX這種命名空間基本是由ContextNamespaceHandler來做處理.
他會解析一大堆標簽,其中我們主要要研究的額就是component-scan和annotation-config...功能有一部分重疊.
ComponentScanBeanDefinitionParser的parse方法會調用org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object) 這個方法
看方法內部不難看出它往registry(BeanFactory)中添加了很多特殊的BeanPostProcessor (或者其子類).我們比較關心的是AutowiredAnnotationBeanPostProcessor
BeanPostProcessor
BPP這些特殊的bean會參與Spring的生命周期.
這個類最重要的地方在於impl了InstantiationAwareBeanPostProcessor和MergedBeanDefinitionPostProcessor了.
其中有3個方法的覆蓋比較關鍵.
第一個是MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition
這個時間點大致是在BeanFactory准備根據beanDifinition去創建bean的時候.會回調這個方法.
AutowiredAnnotationBeanPostProcessor在這一步驟中取查找bean有標記了@Autowired的field,method等InjectionMetadata.InjectedElement的實現..
具體的業務邏輯就不想詳細說明了.基本就是通過反射去查找要注入的元素,然后封裝到元信息里保存下來.
第二個是InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation返回為true.(常規的bean都會返回true)
InstantiationAwareBeanPostProcessor可以通過這個false參數來阻止屬性的注入.
當然正常情況下這里一般方式(比如XML中注入屬性)也是允許的,所以這里返回true.這就意味着bean定義和bean的部分屬性可以定義在XML中走一般的屬性注入.
而這個bean的部分屬性加上@Autowired,通過注解注入也是可以的..只是可能很少會有人這么做.
當然,設置為false的話@Autowired也不能注入.因為有短路原則.滿足這種情況的話只有BeanPostProcessor.postProcessAfterInitialization會被調用.
第三個方法是InstantiationAwareBeanPostProcessor.postProcessPropertyValues
這個回調函數發生的時間是在BeanFactory去populateBean的時候.也就是說bean已經new了.正在初始化他的屬性,且通過正常方式(比如XML里定義的屬性)已經完成的時候.
通過獲取之前第一步中記錄下來的metaData.InjectedElement.對於每一個element去掉inject方法.
method和field因為是2種實現類.所以方法實現會有一點點區別.但是大致還是一樣的...可以來看看field的.
最核心的也就是.問BF去取bean.
我有一個field.我有一個需要的type.你BF找到bean給我..就這樣.
https://www.cnblogs.com/binarylei/p/12337145.html
可以參考上面這篇文章怎么從BF中取bean.
絕大部分情況下基本就是從BeanDifination中取出類型匹配的bean的name.然后再去找對應的bean.
找到了bean以后就通過field.set去設置一下即可.
小結
1.Spring中這么多騷操作離不開BeanPostProcessor等特殊的bean.在XML對應的applicationContext的時候通過NamspaceHandler解析XML節點,並去注冊AutowiredAnnotationBeanPostProcessor等bean.
2.AutowiredAnnotationBeanPostProcessor
通過MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition在doCreateBean當前bean的時候收集當前的需要@Auwotired的element的元數據信息
通過InstantiationAwareBeanPostProcessor.postProcessPropertyValues在populateBean的時候,即設置當前bean的屬性的時候獲取之前的需要注入的elment.然后去BF中獲取對應的bean.並set.