准备依赖注入
在前面的分析中我們已經(jīng)了解到Bean 的依賴注入主要分為兩個(gè)步驟,首先調(diào)用createBeanInstance()方法生成Bean 所包含的Java 對(duì)象實(shí)例。然后,調(diào)用populateBean()方法,對(duì)Bean 屬性的依賴注入進(jìn)行處理。
上面我們已經(jīng)分析了容器初始化生成Bean 所包含的Java 實(shí)例對(duì)象的過程,現(xiàn)在我們繼續(xù)分析生成對(duì)象后,Spring IOC 容器是如何將Bean 的屬性依賴關(guān)系注入Bean 實(shí)例對(duì)象中并設(shè)置好的,回到AbstractAutowireCapableBeanFactory 的populateBean()方法,對(duì)屬性依賴注入的代碼如下:
//將Bean屬性設(shè)置到生成的實(shí)例對(duì)象上 protected 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.boolean continueWithPropertyPopulation = true;if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {continueWithPropertyPopulation = false;break;}}}}if (!continueWithPropertyPopulation) {return;}//獲取容器在解析Bean定義資源時(shí)為BeanDefiniton中設(shè)置的屬性值PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);//對(duì)依賴注入處理,首先處理autowiring自動(dòng)裝配的依賴注入if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {MutablePropertyValues newPvs = new MutablePropertyValues(pvs);// Add property values based on autowire by name if applicable.//根據(jù)Bean名稱進(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類型進(jìn)行autowiring自動(dòng)裝配處理if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {autowireByType(beanName, mbd, bw, newPvs);}pvs = newPvs;}//對(duì)非autowiring的屬性進(jìn)行依賴注入處理boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);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;pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);if (pvs == null) {return;}}}}if (needsDepCheck) {checkDependencies(beanName, mbd, filteredPds, pvs);}}if (pvs != null) {//對(duì)屬性進(jìn)行注入applyPropertyValues(beanName, mbd, bw, pvs);} } //解析并注入依賴屬性的過程 protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {if (pvs.isEmpty()) {return;}//封裝屬性值MutablePropertyValues mpvs = null;List<PropertyValue> original;if (System.getSecurityManager() != null) {if (bw instanceof BeanWrapperImpl) {//設(shè)置安全上下文,JDK安全機(jī)制((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());}}if (pvs instanceof MutablePropertyValues) {mpvs = (MutablePropertyValues) pvs;//屬性值已經(jīng)轉(zhuǎn)換if (mpvs.isConverted()) {// Shortcut: use the pre-converted values as-is.try {//為實(shí)例化對(duì)象設(shè)置屬性值bw.setPropertyValues(mpvs);return;}catch (BeansException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", ex);}}//獲取屬性值對(duì)象的原始類型值original = mpvs.getPropertyValueList();}else {original = Arrays.asList(pvs.getPropertyValues());}//獲取用戶自定義的類型轉(zhuǎn)換TypeConverter converter = getCustomTypeConverter();if (converter == null) {converter = bw;}//創(chuàng)建一個(gè)Bean定義屬性值解析器,將Bean定義中的屬性值解析為Bean實(shí)例對(duì)象的實(shí)際值BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);// Create a deep copy, resolving any references for values.//為屬性的解析值創(chuàng)建一個(gè)拷貝,將拷貝的數(shù)據(jù)注入到實(shí)例對(duì)象中List<PropertyValue> deepCopy = new ArrayList<>(original.size());boolean resolveNecessary = false;for (PropertyValue pv : original) {//屬性值不需要轉(zhuǎn)換if (pv.isConverted()) {deepCopy.add(pv);}//屬性值需要轉(zhuǎn)換else {String propertyName = pv.getName();//原始的屬性值,即轉(zhuǎn)換之前的屬性值Object originalValue = pv.getValue();//轉(zhuǎn)換屬性值,例如將引用轉(zhuǎn)換為IOC容器中實(shí)例化對(duì)象引用Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);//轉(zhuǎn)換之后的屬性值Object convertedValue = resolvedValue;//屬性值是否可以轉(zhuǎn)換boolean convertible = bw.isWritableProperty(propertyName) &&!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);if (convertible) {//使用用戶自定義的類型轉(zhuǎn)換器轉(zhuǎn)換屬性值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.//存儲(chǔ)轉(zhuǎn)換后的屬性值,避免每次屬性注入時(shí)的轉(zhuǎn)換工作if (resolvedValue == originalValue) {if (convertible) {//設(shè)置屬性轉(zhuǎn)換之后的值pv.setConvertedValue(convertedValue);}deepCopy.add(pv);}//屬性是可轉(zhuǎn)換的,且屬性原始值是字符串類型,且屬性的原始類型值不是//動(dòng)態(tài)生成的字符串,且屬性的原始值不是集合或者數(shù)組類型else if (convertible && originalValue instanceof TypedStringValue &&!((TypedStringValue) originalValue).isDynamic() &&!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {pv.setConvertedValue(convertedValue);//重新封裝屬性的值deepCopy.add(pv);}else {resolveNecessary = true;deepCopy.add(new PropertyValue(pv, convertedValue));}}}if (mpvs != null && !resolveNecessary) {//標(biāo)記屬性值已經(jīng)轉(zhuǎn)換過mpvs.setConverted();}// Set our (possibly massaged) deep copy.//進(jìn)行屬性依賴注入try {bw.setPropertyValues(new MutablePropertyValues(deepCopy));}catch (BeansException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", ex);} }分析上述代碼,我們可以看出,對(duì)屬性的注入過程分以下兩種情況:
1)、屬性值類型不需要強(qiáng)制轉(zhuǎn)換時(shí),不需要解析屬性值,直接準(zhǔn)備進(jìn)行依賴注入。
2)、屬性值需要進(jìn)行類型強(qiáng)制轉(zhuǎn)換時(shí),如對(duì)其他對(duì)象的引用等,首先需要解析屬性值,然后對(duì)解析后的屬性值進(jìn)行依賴注入。
對(duì)屬性值的解析是在BeanDefinitionValueResolver 類中的resolveValueIfNecessary()方法中進(jìn)行的,對(duì)屬性值的依賴注入是通過bw.setPropertyValues()方法實(shí)現(xiàn)的,在分析屬性值的依賴注入之前,我們先分析一下對(duì)屬性值的解析過程。
?
總結(jié)
- 上一篇: 执行Bean 实例化
- 下一篇: 解析属性注入规则