日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

Spring Ioc源码分析 之 Bean的加载(6):属性填充(populateBean())

發(fā)布時(shí)間:2025/3/15 javascript 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring Ioc源码分析 之 Bean的加载(6):属性填充(populateBean()) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

“屬性填充”,也是在populateBean()方法中。

首先回顧下CreateBean的主流程:

  • 如果是單例模式,從factoryBeanInstanceCache 緩存中獲取BeanWrapper 實(shí)例對(duì)象并刪除緩存
  • 調(diào)用createBeanInstance() 實(shí)例化 bean
  • 后置處理
  • 單例模式的循環(huán)依賴(lài)處理
  • 屬性填充
  • 初始化 bean 實(shí)例對(duì)象
  • 依賴(lài)檢查
  • 注冊(cè)bean的銷(xiāo)毀方法
  • 本文主要分析第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è)步驟:

  • 判斷是否有自定義屬性注入
  • 屬性注入(xml方式)
  • 屬性注入(注解方式)
  • 依賴(lài)檢查(xml方式)
  • 注入屬性(xml方式)
    • 1.1、判斷是否有自定義屬性注入
      在上述代碼<1>處:
    /** 在設(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 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; }

    這部分邏輯注釋上已經(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、屬性注入(注解方式)
    PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);if (hasInstAwareBpps) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;// 處理依賴(lài)注入(注解方式) 如@Value()、@Resource、@Autowirepvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);if (pvs == null) {return;}}}}

    這段代碼就是我們要分析的核心。
    首先判斷是否已經(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è)方法用來(lái)在對(duì)象實(shí)例化前直接返回一個(gè)對(duì)象(如代理對(duì)象)來(lái)代替通過(guò)內(nèi)置的實(shí)例化流程創(chuàng)建對(duì)象;@Nullable default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {return null; } //在對(duì)象實(shí)例化完畢執(zhí)行populateBean之前 如果返回false則spring不再對(duì)對(duì)應(yīng)的bean實(shí)例進(jìn)行自動(dòng)依賴(lài)注入。 default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {return true; }//這里是在spring處理完默認(rèn)的成員屬性,應(yīng)用到指定的bean之前進(jìn)行回調(diào),可以用來(lái)檢查和修改屬性,最終返回的PropertyValues會(huì)應(yīng)用到bean中//@Autowired、@Resource、@Value等就是根據(jù)這個(gè)方法來(lái)實(shí)現(xiàn)最終注入依賴(lài)的屬性的。 @Nullable default PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {return pvs; }

    我們主要看第三個(gè)方法postProcessPropertyValues(),這個(gè)方法就是通過(guò)注解進(jìn)行屬性注入的具體實(shí)現(xiàn)。
    該方法主要有3個(gè)實(shí)現(xiàn),分別對(duì)應(yīng)了不同的注解。

  • AutowiredAnnotationBeanPostProcessor可以處理@Autowire、@Value
  • CommonAnnotationBeanPostProcessor 可以處理@Resource
  • RequiredAnnotationBeanPostProcessor 可以處理@Required
    • 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)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。