spring原始碼深度解析— IOC 之 屬性填充
doCreateBean()
主要用於完成 bean 的建立和初始化工作,我們可以將其分為四個過程:
createBeanInstance()
例項化 beanpopulateBean()
屬性填充- 迴圈依賴的處理
initializeBean()
初始化 bean
第一個過程例項化 bean在前面一篇部落格中已經分析完了,這篇部落格開始分析 屬性填充,也就是 populateBean()
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) { PropertyValues pvs = mbd.getPropertyValues(); if (bw == null) { if (!pvs.isEmpty()) { 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; //返回值為是否繼續填充bean if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } } //如果後處理器發出停止填充命令則終止後續的執行 if (!continueWithPropertyPopulation) { return; } 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. //根據名稱自動注入 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. //根據型別自動注入 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } //後處理器已經初始化 boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); //需要依賴檢查 boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); if (hasInstAwareBpps || needsDepCheck) { 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) { //依賴檢查,對應depends-on屬性,3.0已經棄用此屬性 checkDependencies(beanName, mbd, filteredPds, pvs); } } //將屬性應用到bean中 //將所有ProtertyValues中的屬性填充至BeanWrapper中。 applyPropertyValues(beanName, mbd, bw, pvs); }
我們詳細分析下populateBean的流程:
(1)首先進行屬性是否為空的判斷
(2)通過呼叫InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)方法來控制程式是否繼續進行屬性填充
(3)根據注入型別(byName/byType)提取依賴的bean,並統一存入PropertyValues中
(4)應用InstantiationAwareBeanPostProcessor的postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName)方法,對屬性獲取完畢填充前的再次處理,典型的應用是RequiredAnnotationBeanPostProcesser類中對屬性的驗證
上面步驟中有幾個地方是我們比較感興趣的,它們分別是依賴注入(autowireByName/autowireByType)以及屬性填充,接下來進一步分析這幾個功能的實現細節
自動注入
Spring 會根據注入型別( byName / byType )的不同,呼叫不同的方法(autowireByName()
/ autowireByType()
)來注入屬性值。
autowireByName()
protected void autowireByName( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { // 獲取 Bean 物件中非簡單屬性 String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { // 如果容器中包含指定名稱的 bean,則將該 bean 注入到 bean中 if (containsBean(propertyName)) { // 遞迴初始化相關 bean Object bean = getBean(propertyName); // 為指定名稱的屬性賦予屬性值 pvs.add(propertyName, bean); // 屬性依賴注入 registerDependentBean(propertyName, beanName); if (logger.isDebugEnabled()) { logger.debug("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 的非簡單屬性,什麼叫做非簡單屬性呢?就是型別為物件型別的屬性,但是這裡並不是將所有的物件型別都都會找到,比如 8 個原始型別,String 型別 ,Number型別、Date型別、URL型別、URI型別等都會被忽略,如下:
protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) { Set<String> result = new TreeSet<>(); PropertyValues pvs = mbd.getPropertyValues(); 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); }
這裡獲取的就是需要依賴注入的屬性。
autowireByName()函式的功能就是根據傳入的引數中的pvs中找出已經載入的bean,並遞迴例項化,然後加入到pvs中
autowireByType
autowireByType與autowireByName對於我們理解與使用來說複雜程度相似,但是實現功能的複雜度卻不一樣,我們看下方法程式碼:
protected void autowireByType( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { TypeConverter converter = getCustomTypeConverter(); if (converter == null) { converter = bw; } Set<String> autowiredBeanNames = new LinkedHashSet<String>(4); //尋找bw中需要依賴注入的屬性 String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { try { PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName); // Don't try autowiring by type for type Object: never makes sense, // even if it technically is a unsatisfied, non-simple property. if (!Object.class.equals(pd.getPropertyType())) { //探測指定屬性的set方法 MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); // Do not allow eager init for type matching in case of a prioritized post-processor. boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass()); DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager); //解析指定beanName的屬性所匹配的值,並把解析到的屬性名稱儲存在autowiredBeanNames中, Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter); if (autowiredArgument != null) { pvs.add(propertyName, autowiredArgument); } for (String autowiredBeanName : autowiredBeanNames) { //註冊依賴 registerDependentBean(autowiredBeanName, beanName); if (logger.isDebugEnabled()) { logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + autowiredBeanName + "'"); } } autowiredBeanNames.clear(); } } catch (BeansException ex) { throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex); } } }
根據名稱第一步與根據屬性第一步都是尋找bw中需要依賴注入的屬性,然後遍歷這些屬性並尋找型別匹配的bean,其中最複雜就是尋找型別匹配的bean。spring中提供了對集合的型別注入支援,如使用如下註解方式:
@Autowired private List<Test> tests;
這種方式spring會把所有與Test匹配的型別找出來並注入到tests屬性中,正是由於這一因素,所以在autowireByType函式,新建了局部遍歷autowireBeanNames,用於儲存所有依賴的bean,如果只是對非集合類的屬性注入來說,此屬性並無用處。
對於尋找型別匹配的邏輯實現是封裝在了resolveDependency函式中,其實現如下:
public Object resolveDependency(DependencyDescriptor descriptor, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException { descriptor.initParameterNameDiscovery(getParameterNameDiscoverer()); if (descriptor.getDependencyType().equals(ObjectFactory.class)) { //ObjectFactory類注入的特殊處理 return new DependencyObjectFactory(descriptor, beanName); } else if (descriptor.getDependencyType().equals(javaxInjectProviderClass)) { //javaxInjectProviderClass類注入的特殊處理 return new DependencyProviderFactory().createDependencyProvider(descriptor, beanName); } else { //通用處理邏輯 return doResolveDependency(descriptor, descriptor.getDependencyType(), beanName, autowiredBeanNames, typeConverter); } } protected Object doResolveDependency(DependencyDescriptor descriptor, Class<?> type, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException { /* * 用於支援Spring中新增的註解@Value */ Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); if (value != null) { if (value instanceof String) { String strVal = resolveEmbeddedValue((String) value); BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null); value = evaluateBeanDefinitionString(strVal, bd); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); return (descriptor.getField() != null ? converter.convertIfNecessary(value, type, descriptor.getField()) : converter.convertIfNecessary(value, type, descriptor.getMethodParameter())); } //如果解析器沒有成功解析,則需要考慮各種情況 //屬性是陣列型別 if (type.isArray()) { Class<?> componentType = type.getComponentType(); //根據屬性型別找到beanFactory中所有型別的匹配bean, //返回值的構成為:key=匹配的beanName,value=beanName對應的例項化後的bean(通過getBean(beanName)返回) Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, descriptor); if (matchingBeans.isEmpty()) { //如果autowire的require屬性為true而找到的匹配項卻為空則只能丟擲異常 if (descriptor.isRequired()) { raiseNoSuchBeanDefinitionException(componentType, "array of " + componentType.getName(), descriptor); } return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); //通過轉換器將bean的值轉換為對應的type型別 return converter.convertIfNecessary(matchingBeans.values(), type); } //屬性是Collection型別 else if (Collection.class.isAssignableFrom(type) && type.isInterface()) { Class<?> elementType = descriptor.getCollectionType(); if (elementType == null) { if (descriptor.isRequired()) { throw new FatalBeanException("No element type declared for collection [" + type.getName() + "]"); } return null; } Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, descriptor); if (matchingBeans.isEmpty()) { if (descriptor.isRequired()) { raiseNoSuchBeanDefinitionException(elementType, "collection of " + elementType.getName(), descriptor); } return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); return converter.convertIfNecessary(matchingBeans.values(), type); } //屬性是Map型別 else if (Map.class.isAssignableFrom(type) && type.isInterface()) { Class<?> keyType = descriptor.getMapKeyType(); if (keyType == null || !String.class.isAssignableFrom(keyType)) { if (descriptor.isRequired()) { throw new FatalBeanException("Key type [" + keyType + "] of map [" + type.getName() + "] must be assignable to [java.lang.String]"); } return null; } Class<?> valueType = descriptor.getMapValueType(); if (valueType == null) { if (descriptor.isRequired()) { throw new FatalBeanException("No value type declared for map [" + type.getName() + "]"); } return null; } Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType, descriptor); if (matchingBeans.isEmpty()) { if (descriptor.isRequired()) { raiseNoSuchBeanDefinitionException(valueType, "map with value type " + valueType.getName(), descriptor); } return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } return matchingBeans; } else { Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor); if (matchingBeans.isEmpty()) { if (descriptor.isRequired()) { raiseNoSuchBeanDefinitionException(type, "", descriptor); } return null; } if (matchingBeans.size() > 1) { String primaryBeanName = determinePrimaryCandidate(matchingBeans, descriptor); if (primaryBeanName == null) { throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet()); } if (autowiredBeanNames != null) { autowiredBeanNames.add(primaryBeanName); } return matchingBeans.get(primaryBeanName); } // We have exactly one match. Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next(); if (autowiredBeanNames != null) { autowiredBeanNames.add(entry.getKey()); } //已經確定只有一個匹配項 return entry.getValue(); } }
applyPropertyValues
程式執行到這裡,已經完成了對所有注入屬性的獲取,但是獲取的屬性是以PropertyValues形式存在的,還並沒有應用到已經例項化的bean中,這一工作是在applyPropertyValues中。繼續跟蹤到方法體中:
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { if (pvs == null || pvs.isEmpty()) { return; } MutablePropertyValues mpvs = null; List<PropertyValue> original; if (System.getSecurityManager() != null) { if (bw instanceof BeanWrapperImpl) { ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext()); } } if (pvs instanceof MutablePropertyValues) { mpvs = (MutablePropertyValues) pvs; //如果mpvs中的值已經被轉換為對應的型別那麼可以直接設定到beanwapper中 if (mpvs.isConverted()) { // Shortcut: use the pre-converted values as-is. try { bw.setPropertyValues(mpvs); return; } catch (BeansException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Error setting property values", ex); } } original = mpvs.getPropertyValueList(); } else { //如果pvs並不是使用MutablePropertyValues封裝的型別,那麼直接使用原始的屬性獲取方法 original = Arrays.asList(pvs.getPropertyValues()); } 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. List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size()); boolean resolveNecessary = false; //遍歷屬性,將屬性轉換為對應類的對應屬性的型別 for (PropertyValue pv : original) { if (pv.isConverted()) { deepCopy.add(pv); } else { String propertyName = pv.getName(); Object originalValue = pv.getValue(); Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue); Object convertedValue = resolvedValue; boolean convertible = bw.isWritableProperty(propertyName) && !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName); if (convertible) { 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) { pv.setConvertedValue(convertedValue); } deepCopy.add(pv); } 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) { mpvs.setConverted(); } // Set our (possibly massaged) deep copy. try { bw.setPropertyValues(new MutablePropertyValues(deepCopy)); } catch (BeansException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Error setting property values", ex); } }
我們來看看具體的屬性賦值過程
public class MyTestBean { private String name ; public MyTestBean(String name) { this.name = name; } public MyTestBean() { } public String getName() { return name; } public void setName(String name) { this.name = name; } } <bean id="myTestBean" class="chenhao.spring01.MyTestBean"> <property name="name" value="chenhao"></property> </bean>
如上 bw.setPropertyValues 最終都會走到如下方法
@Override public void setValue(final @Nullable Object value) throws Exception { //獲取writeMethod,也就是我們MyTestBean的setName方法 final Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ? ((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() : this.pd.getWriteMethod()); if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { ReflectionUtils.makeAccessible(writeMethod); return null; }); try { AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> writeMethod.invoke(getWrappedInstance(), value), acc); } catch (PrivilegedActionException ex) { throw ex.getException(); } } else { ReflectionUtils.makeAccessible(writeMethod); //通過反射呼叫方法進行賦值 writeMethod.invoke(getWrappedInstance(), value); } }
Debug如下
就是利用反射進行呼叫物件的set方法賦值
至此,doCreateBean()
第二個過程:屬性填充 已經分析完成了,下篇分析第三個過程:迴圈依賴的處理,其實迴圈依賴並不僅僅只是在 doCreateBean()
中處理,其實在整個載入 bean 的過程中都有涉及,所以下篇內容並不僅僅只侷限於 doCreateBean()
。
&n