該系列文章是本人在學習 Spring 的過程當中總結下來的,裏面涉及到相關源碼,可能對讀者不太友好,請結合個人源碼註釋 Spring 源碼分析 GitHub 地址 進行閱讀html
Spring 版本:5.1.14.RELEASEjava
開始閱讀這一系列文章以前,建議先查看《深刻了解 Spring IoC(面試題)》這一篇文章git
該系列其餘文章請查看:《死磕 Spring 之 IoC 篇 - 文章導讀》github
當咱們顯示或者隱式地調用AbstractBeanFactory
的 getBean(...)
方法時,會觸發 Bean 的加載,在《開啓 Bean 的加載》文章中分析了整個加載過程。面試
對於不一樣做用域的 Bean,底層都會調用 AbstractAutowireCapableBeanFactory
的 createBean(...)
方法進行建立,在《Bean 的建立過程》文章中分析了整個建立過程。建立 Bean 的過程當中,在獲取到的一個實例對象後,裏面的相關屬性也許是空的,那麼接下來要作的就是將須要填充的屬性進行依賴注入,而後再進行後續的初始化工做。整個的屬性填充過程很是複雜,由於配置的屬性值多是一個表達式,須要解析,類型也可能不對,須要進行類型轉換,還多是一個對象,須要找到對應的 Bean 而後注入(依賴注入),存在有各類處理,本文將會分析建立 Bean 過程當中的屬性填充階段。spring
先來回顧一下建立 Bean 過程當中屬性填充階段對應的代碼:數組
// AbstractAutowireCapableBeanFactory#doCreateBean(...) 方法 // Initialize the bean instance. // 開始初始化 `bean` Object exposedObject = bean; try { // <4> 對 `bean` 進行屬性填充,注入對應的屬性值 populateBean(beanName, mbd, instanceWrapper); // <5> 初始化這個 `exposedObject`,調用其初始化方法 exposedObject = initializeBean(beanName, exposedObject, mbd); } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); } }
在建立好實例對象後,這個對象的屬性尚未賦值,因此將這個實例對象的相關屬性進行賦值,也就是上面的第 <4>
步緩存
populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)
方法,屬性填充,以下:app
// AbstractAutowireCapableBeanFactory.java protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { // <1> 若是實例對象爲空,則進行下面的判斷 if (bw == null) { // <1.1> 這個 Bean 有屬性,則拋出異常 if (mbd.hasPropertyValues()) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } // <1.2> 不然,不用屬性填充,直接 `return` 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. // <2> 實例化階段的後置處理,若是知足這兩個條件 if (!mbd.isSynthetic() // RootBeanDefinition 不是用戶定義的(由 Spring 解析出來的) && hasInstantiationAwareBeanPostProcessors()) { // 是否有 InstantiationAwareBeanPostProcessor 處理器 // <2.1> 遍歷全部的 BeanPostProcessor for (BeanPostProcessor bp : getBeanPostProcessors()) { // 若是爲 InstantiationAwareBeanPostProcessor 類型 if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // <2.2> 對實例化對象進行後置處理 // 注意若是返回 false,直接 `return`,不會調用後面的 InstantiationAwareBeanPostProcessor 處理器,也不會進行接下來的屬性填充 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return; } } } } // <3> 獲取 `pvs`,承載當前對象的屬性值 PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); // <4> 獲取這個 Bean 的注入模式,默認爲 **AUTOWIRE_NO**,例如能夠經過 `@Bean` 註解的 `autowire` 屬性配置注入模式 int resolvedAutowireMode = mbd.getResolvedAutowireMode(); // <4.1> 若是注入模式爲 **AUTOWIRE_BY_NAME** 或者 **AUTOWIRE_BY_TYPE**,則經過下面的方式獲取屬性值 if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { // <4.2> 將 `pvs` 封裝成 MutablePropertyValues 對象 `newPvs`(容許對屬性進行相關操做) MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. // <4.3> **AUTOWIRE_BY_NAME** 模式,經過名稱獲取相關屬性值,保存在 `newPvs` 中 if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. // <4.4> **AUTOWIRE_BY_TYPE** 模式,經過類型獲取相關屬性值,保存在 `newPvs` 中 if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } // <4.5> 將 `newPvs` 複製給 `pvs` pvs = newPvs; } // 是否有 InstantiationAwareBeanPostProcessor 處理器 boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); // 是否須要進行依賴檢查,默認爲 true boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); PropertyDescriptor[] filteredPds = null; // <5> 經過 InstantiationAwareBeanPostProcessor 處理器(若是有)對 `pvs` 進行處理 if (hasInstAwareBpps) { if (pvs == null) { pvs = mbd.getPropertyValues(); } // <5.1> 遍歷全部的 BeanPostProcessor for (BeanPostProcessor bp : getBeanPostProcessors()) { // 若是爲 InstantiationAwareBeanPostProcessor 類型 if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; /** * Spring 內部的 InstantiationAwareBeanPostProcessor 處理器: * {@link AutowiredAnnotationBeanPostProcessor#postProcessProperties} 會解析 @Autowired 和 @Value 註解標註的屬性,獲取對應屬性值; * {@link org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessProperties} 會解析 @Resource 註解標註的屬性,獲取對應的屬性值 */ // <5.2> 調用處理器的 `postProcessProperties(...)` 方法,對 `pvs` 進行後置處理 PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); // <5.3> 若是上一步的處理結果爲空,多是新版本致使的(Spring 5.1 以前沒有上面這個方法),則須要兼容老版本 if (pvsToUse == null) { // <5.3.1> 找到這個 Bean 的全部 `java.beans.PropertyDescriptor` 屬性描述器(包含這個屬性的全部信息) if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } // <5.3.2> 調用處理器的 `postProcessPropertyValues(...)` 方法,對 `pvs` 進行後置處理 pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); // <5.3.3> 若是處理後的 PropertyValues 對象爲空,直接 `return`,則不會調用後面的 InstantiationAwareBeanPostProcessor 處理器,也不會進行接下來的屬性填充 if (pvsToUse == null) { return; } } // <5.4> 將處理後的 `pvsToUse` 複製給 `pvs` pvs = pvsToUse; } } } // <6> 依賴檢查 if (needsDepCheck) { // <6.1> 找到這個 Bean 的全部 `java.beans.PropertyDescriptor` 屬性描述器(包含這個屬性的全部信息) if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } // <6.2> 依賴檢查,若是沒有找到對應的屬性值,則根據檢查策略進行拋出異常(默認不會) checkDependencies(beanName, mbd, filteredPds, pvs); } // <7> 若是 `pvs` 不爲空,則將裏面的屬性值設置到當前 Bean 對應的屬性中(依賴注入) // 前面找到的屬性值並無設置到 Bean 中,且屬性值多是一個表達式,類型也可能也不對,須要先進行處理和類型轉換,而後再設置到該實例對象中 if (pvs != null) { applyPropertyValues(beanName, mbd, bw, pvs); } }
過程大體以下:源碼分析
若是實例對象爲null
,則進行下面的判斷
return
實例化階段的後置處理,若是知足這兩個條件:RootBeanDefinition 不是用戶定義的(由 Spring 解析出來的)、是否有 InstantiationAwareBeanPostProcessor 處理器
遍歷全部的 BeanPostProcessor
若是爲 InstantiationAwareBeanPostProcessor 類型,則對實例化對象進行後置處理
注意,若是返回 false,直接 return
,不會調用後面的 InstantiationAwareBeanPostProcessor 處理器,也不會進行接下來的屬性填充
獲取 pvs
,承載當前對象的屬性值
獲取這個 Bean 的注入模式,默認爲 AUTOWIRE_NO,例如能夠經過 @Bean
註解的 autowire
屬性配置注入模式
pvs
封裝成 MutablePropertyValues 對象 newPvs
(容許對屬性進行相關操做)newPvs
中,調用 autowireByName(...)
方法newPvs
中,調用 autowireByType(...)
方法newPvs
複製給 pvs
經過 InstantiationAwareBeanPostProcessor 處理器(若是有)對 pvs
進行處理
postProcessProperties(...)
方法,對 pvs
進行後置處理java.beans.PropertyDescriptor
屬性描述器(包含這個屬性的全部信息)postProcessPropertyValues(...)
方法,對 pvs
進行後置處理return
,則不會調用後面的處理器,也不會進行接下來的屬性填充pvsToUse
複製給 pvs
依賴檢查
java.beans.PropertyDescriptor
屬性描述器(包含這個屬性的全部信息)若是 pvs
不爲空,則將裏面的屬性值設置到當前 Bean 對應的屬性中(依賴注入),調用 applyPropertyValues(...)
方法
前面找到的屬性值並無設置到 Bean 中,且屬性值多是一個表達式,類型也可能也不對,須要先進行處理和類型轉換,而後再設置到該實例對象中
整個的屬性填充過程很是的複雜,接下來進行歸納:
false
表示不須要進行接下來的屬性填充過程@Autowired
、@Value
等註解標註的屬性會經過這裏找到對應的屬性值(或對象)上面有兩種注入模式:AUTOWIRE_BY_NAME 和 AUTOWIRE_BY_TYPE,默認爲 AUTOWIRE_NO,接下來先來看看這兩種注入模式的實現
autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs)
方法,經過名稱獲取相關屬性值,以下:
// AbstractAutowireCapableBeanFactory.java protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { // <1> 獲取當前 Bean 中不滿意的非簡單類型的屬性名稱,也就是沒有定義屬性值的"對象"屬性 String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); // <2> 遍歷這些對象屬性的名稱 for (String propertyName : propertyNames) { // <3> 若是當前容器存在對應的 Bean(經過名稱判斷) if (containsBean(propertyName)) { // <3.1> 根據屬性名稱獲取對應的 `bean` 對象(依賴查找) Object bean = getBean(propertyName); // <3.2> 將 `bean` 添加至 `pvs` pvs.add(propertyName, bean); // <3.3> 將兩個 Bean 之間的依賴關係保存起來 registerDependentBean(propertyName, beanName); if (logger.isTraceEnabled()) { logger.trace("Added autowiring by name from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + propertyName + "'"); } } else { if (logger.isTraceEnabled()) { logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName + "' by name: no matching bean found"); } } } }
過程並不複雜,大體以下:
獲取當前 Bean 中不滿意的非簡單類型的屬性名稱,也就是沒有定義屬性值的"對象"屬性,以下:
// AbstractAutowireCapableBeanFactory.java protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) { Set<String> result = new TreeSet<>(); // 獲取已設置的屬性值 PropertyValues pvs = mbd.getPropertyValues(); // 找到這個 Bean 的全部 PropertyDescriptor 屬性描述器(包含這個屬性的全部信息) PropertyDescriptor[] pds = bw.getPropertyDescriptors(); // 遍歷全部屬性 for (PropertyDescriptor pd : pds) { if (pd.getWriteMethod() != null // 有可寫方法 && !isExcludedFromDependencyCheck(pd) // 不忽略 && !pvs.contains(pd.getName()) // 沒有對應的屬性值 && !BeanUtils.isSimpleProperty(pd.getPropertyType())) // 不是簡單類型(例如一個實體類) { result.add(pd.getName()); } } // 返回這些不滿意的非簡單類型的屬性 return StringUtils.toStringArray(result); }
遍歷這些對象屬性的名稱
若是當前容器存在對應的 Bean(經過名稱判斷)
bean
對象(依賴查找)bean
添加至 pvs
直接根據"對象"名稱經過 getBean(String beanName)
獲取到對應的對象(依賴查找)
autowireByType(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs)
方法,經過類型獲取相關屬性值,以下:
// AbstractAutowireCapableBeanFactory.java protected void autowireByType(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { // <1> 獲取 TypeConverter 類型轉換器,用於取代默認的 PropertyEditor 類型轉換器 // 例如 Spring 3.0 以後的 ConversionService TypeConverter converter = getCustomTypeConverter(); if (converter == null) { converter = bw; } Set<String> autowiredBeanNames = new LinkedHashSet<>(4); // <2> 獲取當前 Bean 中不滿意的非簡單類型的屬性名稱,也就是沒有定義屬性值的"對象"屬性 String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); // <3> 遍歷這些對象屬性的名稱 for (String propertyName : propertyNames) { try { // <3> 獲取這個屬性的 `java.beans.PropertyDescriptor` 屬性描述器(包含這個屬性的全部信息) PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName); // <4> 若是不是 Object 類型(對 Object 類類型的 Bean 進行自動裝配毫無心義),則嘗試找到對應的對象 if (Object.class != pd.getPropertyType()) { // <5> 找到這個屬性的寫方法 MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); // Do not allow eager init for type matching in case of a prioritized post-processor. // 是否能夠提早初始化 boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered); // <6> 建立對應的依賴注入描述對象 DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager); // <7> 依賴注入,找到該屬性對應的對象 Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter); // <8> 若是找到屬性對象,則將該其添加至 `pvs` if (autowiredArgument != null) { pvs.add(propertyName, autowiredArgument); } // <9> 將注入的屬性對象和當前 Bean 以前的關係保存起來 // 由於該屬性多是一個集合,找到了多個對象,因此這裏是一個數組 for (String autowiredBeanName : autowiredBeanNames) { // 將 `autowiredBeanName` 與 `beanName` 的依賴關係保存 registerDependentBean(autowiredBeanName, beanName); if (logger.isTraceEnabled()) { logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + autowiredBeanName + "'"); } } // 清空 `autowiredBeanName` 數組 autowiredBeanNames.clear(); } } catch (BeansException ex) { throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex); } } }
過程大體以下:
java.beans.PropertyDescriptor
屬性描述器(包含這個屬性的全部信息)resolveDependency(...)
方法pvs
根據"對象"名稱經過 resolveDependency(...)
獲取到對應的對象,該方法就是依賴注入的底層實現,整個過程也很是複雜,因此將這部份內容放在下一篇《@Autowired 等註解的實現原理》文章中
調用 InstantiationAwareBeanPostProcessor#postProcessProperties
方法,對前面屬性值進行處理
在前面的AUTOWIRE_BY_NAME 和 AUTOWIRE_BY_TYPE兩種注入模式中,找到的都是普通對象的屬性值,例如 @Autowired、@Value 和 @Resource 註解並無被解析,且默認的注入模式仍是AUTOWIRE_NO,那這些註解是如何被解析的呢?Spring 內部有下面兩個 InstantiationAwareBeanPostProcessor 處理器:
這裏先提一下,具體的實現過程在下一篇《@Autowired 等註解的實現原理》文章中進行分析
applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs)
方法,屬性填充
若是獲取到的 pvs
屬性值對象不爲空,則將裏面的屬性值設置到當前 Bean 對應的屬性中(依賴注入),咱們知道前面找到的屬性值並無設置到 Bean 中,且屬性值多是一個表達式,類型也可能也不對,須要先進行處理和類型轉換,而後再設置到該實例對象中,方法以下:
// AbstractAutowireCapableBeanFactory.java protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { // <1> 沒有相關屬性值,則直接 `return` 返回 if (pvs.isEmpty()) { return; } if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) { ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext()); } // ------------------------開始屬性值的轉換與填充------------------------ MutablePropertyValues mpvs = null; // 定義一個 `original` 集合,承載屬性值(未進行轉換) List<PropertyValue> original; // <2> 若是 `pvs` 是 MutablePropertyValues 類型,則可能已經處理過了 if (pvs instanceof MutablePropertyValues) { mpvs = (MutablePropertyValues) pvs; if (mpvs.isConverted()) { // Shortcut: use the pre-converted values as-is. try { // <2.1> 屬性值已經轉換了,則將這些屬性值設置到當前 Bean 中(反射機制),依賴注入的最終實現!!! bw.setPropertyValues(mpvs); return; } catch (BeansException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Error setting property values", ex); } } // <2.2> 沒有轉換過,則獲取全部的屬性值集合 original = mpvs.getPropertyValueList(); } else { // <2.2> 獲取全部的屬性值集合 original = Arrays.asList(pvs.getPropertyValues()); } // 獲取 TypeConverter 類型轉換器,用於取代默認的 PropertyEditor 類型轉換器 // 例如 Spring 3.0 以後的 ConversionService TypeConverter converter = getCustomTypeConverter(); if (converter == null) { converter = bw; } // 獲取對應的解析器 BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter); // Create a deep copy, resolving any references for values. // <3> 定義一個 `deepCopy` 集合,保存轉換後的屬性值 List<PropertyValue> deepCopy = new ArrayList<>(original.size()); boolean resolveNecessary = false; // <4> 遍歷全部的屬性值,進行轉換(若是有必要) for (PropertyValue pv : original) { // <4.1> 已經轉換過,則直接添加到 `deepCopy` 中 if (pv.isConverted()) { deepCopy.add(pv); } // <4.2> 不然,開始進行轉換 else { String propertyName = pv.getName(); // 轉換以前的屬性值 Object originalValue = pv.getValue(); // <4.2.1> 表達式的處理(若是有必要的話),例如你在 XML 配置的屬性值爲 `${systenm.user}`,則會解析出對應的值 Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue); // 轉換以後的屬性值 Object convertedValue = resolvedValue; // 該屬性是否能夠轉換 boolean convertible = bw.isWritableProperty(propertyName) && // 屬性可寫 !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName); // 不包含 `.` 和 `[` if (convertible) { // <4.2.2> 使用類型轉換器轉換屬性值(若是有必要的話) convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter); } // Possibly store converted value in merged bean definition, // in order to avoid re-conversion for every created bean instance. if (resolvedValue == originalValue) { // 屬性值沒有轉換過 if (convertible) { // <4.2.3> 設置轉換後的值,避免上面的各類判斷 pv.setConvertedValue(convertedValue); } // <4.2.4> 添加到 `deepCopy` 中 deepCopy.add(pv); } // 屬不然屬性值進行了轉換 else if (convertible // 可轉換的 && originalValue instanceof TypedStringValue // 屬性原始值是字符串類型 && !((TypedStringValue) originalValue).isDynamic() // 屬性的原始類型值不是動態生成的字符串 && !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) // 屬性的原始值不是集合或者數組類型 { // <4.2.3> 設置轉換後的值,避免上面的各類判斷 pv.setConvertedValue(convertedValue); // <4.2.4> 添加到 `deepCopy` 中 deepCopy.add(pv); } // 不然 else { // 這個屬性每次都要處理,不能緩存 resolveNecessary = true; // <4.2.4> 添加到 `deepCopy` 中 deepCopy.add(new PropertyValue(pv, convertedValue)); } } } // <5> 若是屬性值不爲空,且不須要每次都處理,則設置爲已轉換 if (mpvs != null && !resolveNecessary) { mpvs.setConverted(); } // Set our (possibly massaged) deep copy. try { // <6> 將屬性值設置到當前 Bean 中(反射機制),依賴注入的最終實現!!! bw.setPropertyValues(new MutablePropertyValues(deepCopy)); } catch (BeansException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Error setting property values", ex); } }
過程大體以下:
return
返回開始屬性值的轉換與填充,先定義一個 original
集合,承載屬性值(未進行轉換)
若是 pvs
是 MutablePropertyValues 類型,則可能已經處理過了,不然,獲取全部的屬性值集合,放入 original
集合中
屬性值已經轉換了,則將這些屬性值設置到當前 Bean 中(反射機制),依賴注入的最終實現!!!
調用 BeanWrapperImpl#setPropertyValues(PropertyValues)
方法
沒有轉換過,則獲取全部的屬性值集合,放入 original
集合中
定義一個 deepCopy
集合,保存轉換後的屬性值
遍歷全部的屬性值,進行轉換(若是有必要)
deepCopy
中${systenm.user}
,則會解析出對應的值deepCopy
中若是屬性值不爲空,且不須要每次都處理,則設置爲已轉換
將屬性值設置到當前 Bean 中(反射機制),依賴注入的最終實現!!!
調用 BeanWrapperImpl#setPropertyValues(PropertyValues)
方法
整個屬性注入過程很是複雜,上面僅列出了關鍵步驟,能夠看到最終會調用 BeanWrapperImpl#setPropertyValues(PropertyValues)
方法將屬性值設置到 Bean 中
在 Bean 的實例化階段獲取到的就是一個 BeanWrapperImpl 對象,因此這裏調用的就是當前 Bean 的 setPropertyValues(PropertyValues)
方法,該方法的底層藉助於 Java Beans 的 java.beans.PropertyDescriptor
屬性描述器,獲取到對應的寫方法,而後經過反射機制設置當前 Bean 的屬性值
當咱們顯示或者隱式地調用AbstractBeanFactory
的 getBean(...)
方法時,會觸發 Bean 的加載,在《開啓 Bean 的加載》文章中分析了整個加載過程。
對於不一樣做用域的 Bean,底層都會調用 AbstractAutowireCapableBeanFactory
的 createBean(...)
方法進行建立,在《Bean 的建立過程》文章中分析了整個建立過程。建立 Bean 的過程當中,在獲取到的一個實例對象後,須要獲取相關屬性值,而後注入到 Bean 中,其中獲取屬性值有三種模式:
AUTOWIRE_NO,默認,不獲取相關屬性值
AUTOWIRE_BY_NAME,經過名稱獲取沒有定義屬性值的"對象"的屬性值,經過 getBean(String beanName)
查找
AUTOWIRE_BY_TYPE,經過類型獲取沒有定義屬性值的"對象"的屬性值,依賴注入的方式
默認狀況下,獲取到已定義的屬性值後不會經過上面的方式去找屬性值,在後續有一個屬性值的後置處理,會調用全部的 InstantiationAwareBeanPostProcessor 處理器的 postProcessProperties 方法進行處理,例如 Spring 內部有兩個 InstantiationAwareBeanPostProcessor 處理器:
在獲取到全部的屬性值後而後經過反射機制設置到 Bean 中
關於 @Autowired、@Value 和 @Resource 註解的實現原理將在下一篇《@Autowired 等註解的實現原理》文章中進行分析