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