javascript
Spring Ioc源码分析 之 Bean的加载(6):属性填充(populateBean())
“屬性填充”,也是在populateBean()方法中。
首先回顧下CreateBean的主流程:
本文主要分析第5步:屬性注入
在Spring中屬性注入有三種方式:
- xml配置:節(jié)點(diǎn)中的default-autowire屬性
- 注解方式:@Value()、@Resource、@Autowire、@Qualifier
- 手動(dòng)get\set方法
本文我們主要分析 注解方式 的屬性注入
一、populateBean(beanName, mbd, instanceWrapper)
//AbstractAutowireCapableBeanFactory.javaprotected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {//校驗(yàn)實(shí)例if (bw == null) {if (mbd.hasPropertyValues()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");}else {// Skip property population phase for null instance.return;}}// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the// state of the bean before properties are set. This can be used, for example,// to support styles of field injection./** 在設(shè)置屬性之前給 InstantiationAwareBeanPostProcessors 最后一次改變 bean 的機(jī)會(huì)。* 關(guān)于這段后置引用,官方的解釋是:讓用戶(hù)可以自定義屬性注入。比如用戶(hù)實(shí)現(xiàn)一* 個(gè) InstantiationAwareBeanPostProcessor 類(lèi)型的后置處理器,并通過(guò)* postProcessAfterInstantiation 方法向 bean 的成員變量注入自定義的信息。當(dāng)然,如果無(wú)* 特殊需求,直接使用配置中的信息注入即可。另外,Spring 并不建議大家直接實(shí)現(xiàn)* InstantiationAwareBeanPostProcessor 接口,如果想實(shí)現(xiàn)這種類(lèi)型的后置處理器,更建議* 通過(guò)繼承 InstantiationAwareBeanPostProcessorAdapter 抽象類(lèi)實(shí)現(xiàn)自定義后置處理器。*/boolean continueWithPropertyPopulation = true;// bean 不是"合成"的,即未由應(yīng)用程序本身定義 && 持有 InstantiationAwareBeanPostProcessor <1> if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {// 遍歷所有的 BeanPostProcessorsfor (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;// 返回值為是否繼續(xù)填充 bean// postProcessAfterInstantiation:如果應(yīng)該在 bean上面設(shè)置屬性則返回 true,否則返回 false// 一般情況下,應(yīng)該是返回true 。// 返回 false 的話(huà),將會(huì)阻止在此 Bean 實(shí)例上調(diào)用任何后續(xù)的 InstantiationAwareBeanPostProcessor 實(shí)例。if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {continueWithPropertyPopulation = false;break;}}}}// 如果后置處理器發(fā)出停止填充命令,則終止后續(xù)操作if (!continueWithPropertyPopulation) {return;}//獲取Bean的屬性值PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);//處理依賴(lài)注入//xml方式 即xml中<beans>節(jié)點(diǎn)中的default-autowire屬性 <2> if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {// 將 PropertyValues 封裝成 MutablePropertyValues 對(duì)象// MutablePropertyValues 允許對(duì)屬性進(jìn)行簡(jiǎn)單的操作,并提供構(gòu)造函數(shù)以支持Map的深度復(fù)制和構(gòu)造。MutablePropertyValues newPvs = new MutablePropertyValues(pvs);// Add property values based on autowire by name if applicable.//根據(jù)Bean名稱(chēng)進(jìn)行autowiring自動(dòng)裝配處理if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {autowireByName(beanName, mbd, bw, newPvs);}// Add property values based on autowire by type if applicable.//根據(jù)Bean類(lèi)型進(jìn)行autowiring自動(dòng)裝配處理if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {autowireByType(beanName, mbd, bw, newPvs);}pvs = newPvs;}// 是否已經(jīng)注冊(cè)了 InstantiationAwareBeanPostProcessorsboolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();//是否需要依賴(lài)檢查(xml)boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); //屬性注入(注解方式)//已經(jīng)注冊(cè)IABP && 需要依賴(lài)檢查 <3> if (hasInstAwareBpps || needsDepCheck) {if (pvs == null) {pvs = mbd.getPropertyValues();}PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);if (hasInstAwareBpps) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;// 具體處理屬性注入(注解方式)!!! 如@Value()、@Resource、@Autowirepvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);if (pvs == null) {return;}}}}//依賴(lài)檢查 (xml) <4> if (needsDepCheck) {checkDependencies(beanName, mbd, filteredPds, pvs);}} <5> if (pvs != null) {//對(duì)屬性進(jìn)行注入 (xml)applyPropertyValues(beanName, mbd, bw, pvs);}}主要分為以下幾個(gè)步驟:
- 1.1、判斷是否有自定義屬性注入
在上述代碼<1>處:
這部分邏輯注釋上已經(jīng)寫(xiě)的很清楚了。
1.2、屬性注入(xml方式)
//xml方式 即xml中<beans>節(jié)點(diǎn)中的default-autowire屬性if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {// 將 PropertyValues 封裝成 MutablePropertyValues 對(duì)象// MutablePropertyValues 允許對(duì)屬性進(jìn)行簡(jiǎn)單的操作,并提供構(gòu)造函數(shù)以支持Map的深度復(fù)制和構(gòu)造。MutablePropertyValues newPvs = new MutablePropertyValues(pvs);// Add property values based on autowire by name if applicable.//根據(jù)Bean名稱(chēng)進(jìn)行autowiring自動(dòng)裝配處理if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {autowireByName(beanName, mbd, bw, newPvs);}// Add property values based on autowire by type if applicable.//根據(jù)Bean類(lèi)型進(jìn)行autowiring自動(dòng)裝配處理if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {autowireByType(beanName, mbd, bw, newPvs);}pvs = newPvs;}這部分代碼主要是來(lái)處理XML方式的屬性注入,例如xml中<beans>節(jié)點(diǎn)中的default-autowire屬性,因?yàn)楸敬蜸pring系列主要是分析注解方式的,這里就不詳細(xì)分析了。感性趣的朋友可以自己趣了解下~
- 1.3、屬性注入(注解方式)
這段代碼就是我們要分析的核心。
首先判斷是否已經(jīng)注冊(cè)InstantiationAwareBeanPostProcessor(實(shí)例化Bean的后置處理器),如果注冊(cè)了,就遍歷所有的后置處理器。 我們先來(lái)了解下InstantiationAwareBeanPostProcessor的類(lèi)圖結(jié)構(gòu):
InstantiationAwareBeanPostProcessor是一個(gè)關(guān)于對(duì)象實(shí)例化前后以及實(shí)例化后設(shè)置propertyValues的回調(diào)處理器。 它有三個(gè)方法:
我們主要看第三個(gè)方法postProcessPropertyValues(),這個(gè)方法就是通過(guò)注解進(jìn)行屬性注入的具體實(shí)現(xiàn)。
該方法主要有3個(gè)實(shí)現(xiàn),分別對(duì)應(yīng)了不同的注解。
- 1.3.1、AutowiredAnnotationBeanPostProcessor
是Spring容器專(zhuān)門(mén)處理配置了自動(dòng)依賴(lài)注入裝配相關(guān)注解(@Autowire、@Value以及其他JSR-330注解)的Bean后置處理器。詳細(xì)說(shuō)明見(jiàn)Spring注解@Autowired源碼分析
- 1.3.2、CommonAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor是Spring中用于處理JavaEE5中常用注解(主要是EJB相關(guān)的注解)和Java6中關(guān)于JAX-WS相關(guān)的注解,可以處理@PostConstruct、@PreDestroy等Bean生命周期相關(guān)事件的注解,該后置處理最核心的是處理@Resource注解,同時(shí)還可以處理JAX-WS相關(guān)的注解。詳細(xì)說(shuō)明見(jiàn)Spring注解@Resource源碼分析
總結(jié) :到這里就已經(jīng)完成了注解方式所有屬性的注入了。
本文轉(zhuǎn)自:https://cloud.tencent.com/developer/article/1521202
與50位技術(shù)專(zhuān)家面對(duì)面20年技術(shù)見(jiàn)證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的Spring Ioc源码分析 之 Bean的加载(6):属性填充(populateBean())的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Spring Ioc源码分析 之 Bea
- 下一篇: Spring Ioc源码分析 之 Bea