Spring Bean的實例化之屬性注入源碼剖析過程
這一章節我們來討論創建Bean過程中的屬性注入,在Spring的IOC容器啟動過程中,會把定義的Bean封裝成BeanDefinition注冊到一個ConcurrentHashMap中,Bean注冊完成后,就會對單利的且lazy-init=false 的Bean進行實例化。創建Bean的代碼在 AbstractAutowireCapableBeanFactory#doCreateBean 中,當Bean創建成功之后,會調用AbstractAutowireCapableBeanFactory#populateBean 方法進行屬性注入。本篇文章主要就是分析該方法是如何實現Bean的屬性注入的。
這里先上一個屬性注入的流程圖,待會兒可以根據這個圖來看代碼
AbstractAutowireCapableBeanFactory#populateBean 方法的主要功能就是屬性填充,源碼如下
//使用 bean 定義中的屬性值填充給定 BeanWrapper 中的 bean 實例。@SuppressWarnings('deprecation') // for postProcessPropertyValuesprotected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {if (bw == null) {//判斷是否有property屬性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的狀態if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {return;}}}}//從 RootBeanDefinition 獲取所有的PropertyValuesPropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);int resolvedAutowireMode = mbd.getResolvedAutowireMode();//根據名字獲取根據type注入if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {MutablePropertyValues newPvs = new MutablePropertyValues(pvs);// Add property values based on autowire by name if applicable.//如果適用,根據名稱添加基于自動裝配的屬性值。if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {autowireByName(beanName, mbd, bw, newPvs);}// Add property values based on autowire by type if applicable.//如果適用,根據類型添加基于自動裝配的屬性值if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {autowireByType(beanName, mbd, bw, newPvs);}pvs = newPvs;}//后置處理器是否已經注冊,初始化好了boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();//是否要檢查依賴,默認falseboolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);PropertyDescriptor[] filteredPds = null;if (hasInstAwareBpps) {if (pvs == null) {pvs = mbd.getPropertyValues();}//獲取后置處理器for (BeanPostProcessor bp : getBeanPostProcessors()) {//如果是Bean實例化后置處理器if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;//PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);if (pvsToUse == null) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}//對需要依賴檢查的屬性進行后置處理pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);if (pvsToUse == null) {return;}}pvs = pvsToUse;}}}if (needsDepCheck) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}checkDependencies(beanName, mbd, filteredPds, pvs);}if (pvs != null) {//依賴注入入口,講屬性應用到Bean中applyPropertyValues(beanName, mbd, bw, pvs);}}
方法中的重要代碼
autowireByName : 根據屬性名進行注入 autowireByType:根據類型注入Bean InstantiationAwareBeanPostProcessor.postProcessPropertyValues :該方法是在工廠將給定的屬性值應用于給定的 bean 之前對給定的屬性值進行處理,比如:RequiredAnnotationBeanPostProcessor類中對屬性的驗證。 applyPropertyValues:屬性的填充autowireByName是根據名字注入,源碼如下
protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {//尋找BeanWrapper中需要依賴的屬性String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);for (String propertyName : propertyNames) {if (containsBean(propertyName)) {//遞歸實例化的BeanObject bean = getBean(propertyName);pvs.add(propertyName, bean);//注冊依賴的Bean,加入 dependentBeanMap 中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,遞歸初始化,然后加入 pvs中
//定義“按類型自動裝配”(按類型的 bean 屬性)行為的抽象方法protected void autowireByType(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {//類型轉換器TypeConverter converter = getCustomTypeConverter();if (converter == null) {converter = bw;}Set<String> autowiredBeanNames = new LinkedHashSet<>(4);//找到需要注入的屬性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 != 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 = !(bw.getWrappedInstance() instanceof PriorityOrdered);//依賴描述DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);//【重要】得到依賴的屬性的值,存儲到 autowiredBeanNames 集合中//提供了對集合如:@Autowired private List<A> as; 支持,根據類型走到所有的Bean注入其中Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);if (autowiredArgument != null) {//添加到pvspvs.add(propertyName, autowiredArgument);}for (String autowiredBeanName : autowiredBeanNames) {//注入依賴的BeanregisterDependentBean(autowiredBeanName, beanName);if (logger.isTraceEnabled()) {logger.trace('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);}}}
看到這,我們大概清楚了,其實在populateBean 方法中會先從RootBeanDefinition 中獲取 Bean的屬性(PropertyValues),同時也會根據RootBeanDefinition的autowireMode自動注入模式來根據name或者type尋主Bean的依賴的屬性。
根據類型注入和根據名字注入都是先從BeanWrapper 中找到Bean的依賴的屬性,然后根據屬性類型找到匹配的Bean,實現依賴注入。還提供了對集合如:@Autowired private List<A> as; 集合注入的支持。
屬性尋找好之后都會封裝成 PropertyValues,然后傳給applyPropertyValues應用到Bean身上。
AbstractAutowireCapableBeanFactory#applyPropertyValues我們可以認為前面的代碼是在為當前Bean尋找依賴的的屬性,封裝到 PropertyValues中,在applyPropertyValues中才是把屬性應用到當前Bean。
//處理對象之間的引用,使用深拷貝protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {if (pvs.isEmpty()) {return;}if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());}MutablePropertyValues mpvs = null;List<PropertyValue> original;if (pvs instanceof MutablePropertyValues) {mpvs = (MutablePropertyValues) pvs;//判斷mpvs中的值是否已經轉成了對應的類型,已經轉了就可以直接設置值到 BeanWrapper了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 {//如果類型不是MutablePropertyValues , 就使用原生屬性獲取方法original = Arrays.asList(pvs.getPropertyValues());}//獲取用戶自定義的型轉換器TypeConverter converter = getCustomTypeConverter();if (converter == null) {converter = bw;}//解析器:用于 bean 工廠實現的 Helper 類,將 bean 定義對象中包含的值,解析為應用于目標 bean 實例的實際值。BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);// Create a deep copy, resolving any references for values.//存放類型轉換過的屬性,把Bean的屬性解析值新建拷貝,把拷貝的數據注入到對象List<PropertyValue> deepCopy = new ArrayList<>(original.size());boolean resolveNecessary = false;//類型轉換,把屬性轉換為對應的類型for (PropertyValue pv : original) {if (pv.isConverted()) {//屬性值不需要轉deepCopy.add(pv);}else {//屬性名String propertyName = pv.getName();//原始屬性值,它的類型是一個 如: RuntimeBeanReference<otherBean> 引用類型Object originalValue = pv.getValue();//轉換屬性值,將引用轉換為 IOC 容器中實例化對象引用 OtherBeanObject 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 ,把依賴的Bean設置給PropertyValuepv.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;//轉換好的依賴的屬性最終放到一個ArrayList中deepCopy.add(new PropertyValue(pv, convertedValue));}}}if (mpvs != null && !resolveNecessary) {mpvs.setConverted();}// Set our (possibly massaged) deep copy.try {//把解析好的屬性 設置到 BeanWrapper 中bw.setPropertyValues(new MutablePropertyValues(deepCopy));}catch (BeansException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, 'Error setting property values', ex);}}
這里主要進行屬性轉換,然后應用到Bean身上,這里的屬性轉換比如: 在BeanDefinition中屬性可能是用字符串類型來描述的,需要把屬性轉成真實的原始屬性類型。
首先判斷屬性是否需要轉換類型,如果不需要轉直接應用于Bean。比如:<property name='otherBean' ref='otherBean' /> 這種屬性值其實是個字符串“otherBean” ,需要解析成容器中的OtherBean實例的引用。 如果屬性值需要類型轉換,比如:屬性值是容器中的另外一個Bean,則需要根據屬性值解析出引用的對象然后注入到對象的屬性上,應用到Bean。通過 BeanDefinitionValueResolver 類中的 resolveValueIfNecessary()方法中進行屬性值的解析, 對屬性值的注入是通過 bw.setPropertyValues()方法完成
解析: BeanDefinitionValueResolver#resolveValueIfNecessary給定一個 PropertyValue根據屬性值進行類型解析,必要時解析對工廠中其他 bean 的引用
@Nullablepublic Object resolveValueIfNecessary(Object argName, @Nullable Object value) {// We must check each value to see whether it requires a runtime reference// to another bean to be resolved.//對屬性值是引用類型的解析if (value instanceof RuntimeBeanReference) {//比如:<property name='xx' ref='xxBean' 就是引用類型,會走這里RuntimeBeanReference ref = (RuntimeBeanReference) value;//對引用類型屬性進行解析return resolveReference(argName, ref);}///對屬性值是引用容器中另一個 Bean 名稱的解析else if (value instanceof RuntimeBeanNameReference) {String refName = ((RuntimeBeanNameReference) value).getBeanName();refName = String.valueOf(doEvaluate(refName));//判斷容器中是否有這個Beanif (!this.beanFactory.containsBean(refName)) {throw new BeanDefinitionStoreException('Invalid bean name ’' + refName + '’ in bean reference for ' + argName);}return refName;}else if (value instanceof BeanDefinitionHolder) {// Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.//解析 BeanDefinitionHolder:包含帶有名稱和別名的 BeanDefinitionBeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;//解析內部 Beanreturn resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());}else if (value instanceof BeanDefinition) {// Resolve plain BeanDefinition, without contained name: use dummy name.//解析純 BeanDefinition,不包含名稱BeanDefinition bd = (BeanDefinition) value;String innerBeanName = '(inner bean)' + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +ObjectUtils.getIdentityHexString(bd);return resolveInnerBean(argName, innerBeanName, bd);}//對數組類型解析else if (value instanceof ManagedArray) {// May need to resolve contained runtime references.ManagedArray array = (ManagedArray) value;Class<?> elementType = array.resolvedElementType;if (elementType == null) {String elementTypeName = array.getElementTypeName();if (StringUtils.hasText(elementTypeName)) {try {elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());array.resolvedElementType = elementType;}catch (Throwable ex) {// Improve the message by showing the context.throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,'Error resolving array type for ' + argName, ex);}}else {elementType = Object.class;}}return resolveManagedArray(argName, (List<?>) value, elementType);}//對集合類型解析else if (value instanceof ManagedList) {// May need to resolve contained runtime references.return resolveManagedList(argName, (List<?>) value);}//對Set類型解析else if (value instanceof ManagedSet) {// May need to resolve contained runtime references.return resolveManagedSet(argName, (Set<?>) value);}//對Map類型解析else if (value instanceof ManagedMap) {// May need to resolve contained runtime references.return resolveManagedMap(argName, (Map<?, ?>) value);}//對Properties解析else if (value instanceof ManagedProperties) {Properties original = (Properties) value;Properties copy = new Properties();original.forEach((propKey, propValue) -> {if (propKey instanceof TypedStringValue) {propKey = evaluate((TypedStringValue) propKey);}if (propValue instanceof TypedStringValue) {propValue = evaluate((TypedStringValue) propValue);}if (propKey == null || propValue == null) {throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,'Error converting Properties key/value pair for ' + argName + ': resolved to null');}copy.put(propKey, propValue);});return copy;}//解析字符串類型的屬性值else if (value instanceof TypedStringValue) {// Convert value to target type here.TypedStringValue typedStringValue = (TypedStringValue) value;Object valueObject = evaluate(typedStringValue);try {//目標類型Class<?> resolvedTargetType = resolveTargetType(typedStringValue);if (resolvedTargetType != null) {//目標類型進行解析return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);}else {//類型沒獲取到,就返回Object類型return valueObject;}}catch (Throwable ex) {// Improve the message by showing the context.throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,'Error converting typed String value for ' + argName, ex);}}else if (value instanceof NullBean) {return null;}else {return evaluate(value);}}
這個方法中就是根據屬性的值的類型進行解析,如:String,Array,List,Set,Map的類型,比較復雜的就是屬性值依賴的是一個Bean,那么就需要根據依賴的Bean的名字找到容器中的Bean的實例,查找如下:
/** * Resolve a reference to another bean in the factory. */ //關聯對象的解析@Nullableprivate Object resolveReference(Object argName, RuntimeBeanReference ref) {try {Object bean;//引用對象的名稱String refName = ref.getBeanName();refName = String.valueOf(doEvaluate(refName));//如果對象在父容器中,從父容器獲取if (ref.isToParent()) {if (this.beanFactory.getParentBeanFactory() == null) {throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,'Can’t resolve reference to bean ’' + refName +'’ in parent factory: no parent factory available');}//如果對象在父容器中,從父容器獲取bean = this.beanFactory.getParentBeanFactory().getBean(refName);}else {//[重要]根據依賴的Bean的名字,從當前容器中獲取Beanbean = this.beanFactory.getBean(refName);//把依賴的Bean的實例和當前對象建議依賴關系,使用 dependentBeanMap 去維護關系this.beanFactory.registerDependentBean(refName, this.beanName);}if (bean instanceof NullBean) {bean = null;}return bean;}catch (BeansException ex) {throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,'Cannot resolve reference to bean ’' + ref.getBeanName() + '’ while setting ' + argName, ex);}} * For each element in the managed array, resolve reference if necessary. */ //解析數組private Object resolveManagedArray(Object argName, List<?> ml, Class<?> elementType) {Object resolved = Array.newInstance(elementType, ml.size());for (int i = 0; i < ml.size(); i++) {Array.set(resolved, i, resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));}return resolved;}/** * For each element in the managed list, resolve reference if necessary. */ //解析Listprivate List<?> resolveManagedList(Object argName, List<?> ml) {List<Object> resolved = new ArrayList<>(ml.size());for (int i = 0; i < ml.size(); i++) {resolved.add(resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));}return resolved;}/** * For each element in the managed set, resolve reference if necessary. */ //解析setprivate Set<?> resolveManagedSet(Object argName, Set<?> ms) {Set<Object> resolved = new LinkedHashSet<>(ms.size());int i = 0;for (Object m : ms) {resolved.add(resolveValueIfNecessary(new KeyedArgName(argName, i), m));i++;}return resolved;}/** * For each element in the managed map, resolve reference if necessary. */ //解析Mapprivate Map<?, ?> resolveManagedMap(Object argName, Map<?, ?> mm) {Map<Object, Object> resolved = new LinkedHashMap<>(mm.size());mm.forEach((key, value) -> {Object resolvedKey = resolveValueIfNecessary(argName, key);Object resolvedValue = resolveValueIfNecessary(new KeyedArgName(argName, key), value);resolved.put(resolvedKey, resolvedValue);});return resolved;}
屬性值解析完成之后 是封裝成一個 MutablePropertyValues,通過 BeanWrapperImpl.setPropertyValues()方法完成值的注入,BeanWrapperImpl中注入方法又是由AbstractPropertyAccessor#setPropertyValue(java.lang.String, java.lang.Object)去完成。
AbstractPropertyAccessor#setPropertyValue@Overridepublic void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid)throws BeansException {List<PropertyAccessException> propertyAccessExceptions = null;//拿到所有的屬性列表List<PropertyValue> propertyValues = (pvs instanceof MutablePropertyValues ?((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()));for (PropertyValue pv : propertyValues) {try {// This method may throw any BeansException, which won’t be caught// here, if there is a critical failure such as no matching field.// We can attempt to deal only with less serious exceptions.//設置屬性值setPropertyValue(pv);}...省略...@Overridepublic void setPropertyValue(String propertyName, @Nullable Object value) throws BeansException {//屬性訪問器AbstractNestablePropertyAccessor nestedPa;try {nestedPa = getPropertyAccessorForPropertyPath(propertyName);}catch (NotReadablePropertyException ex) {throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,'Nested property in path ’' + propertyName + '’ does not exist', ex);}//屬性助手PropertyTokenHolder tokens = getPropertyNameTokens(getFinalPath(nestedPa, propertyName));//通過屬性訪問器為屬性設置值nestedPa.setPropertyValue(tokens, new PropertyValue(propertyName, value));}
這里看到,屬性的注入交給了 AbstractNestablePropertyAccessor 屬性訪問器去完成
protected void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {if (tokens.keys != null) {processKeyedProperty(tokens, pv);}else {//走這里processLocalProperty(tokens, pv);}}private void processLocalProperty(PropertyTokenHolder tokens, PropertyValue pv) {//屬性處理器PropertyHandler ph = getLocalPropertyHandler(tokens.actualName);if (ph == null || !ph.isWritable()) {if (pv.isOptional()) {if (logger.isDebugEnabled()) {logger.debug('Ignoring optional value for property ’' + tokens.actualName +'’ - property not found on bean class [' + getRootClass().getName() + ']');}return;}else {throw createNotWritablePropertyException(tokens.canonicalName);}}Object oldValue = null;try {//原生值Object originalValue = pv.getValue();Object valueToApply = originalValue;...省略...//這是重點,通過 PropertyHandler 把屬性值設置給對象ph.setValue(valueToApply);}catch (TypeMismatchException ex) {throw ex;}
這里的屬性值通過 PropertyHandler去設置
@Overridepublic void setValue(@Nullable Object value) throws Exception {//得到屬性的set方法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);//調用set方法把屬性值設置進去writeMethod.invoke(getWrappedInstance(), value);}}
這里就是得到屬性的set方法,然后調用set方法把值注入進去。
構造器注入參數在之前分析Bean的創建的時候我們就說到,在 AbstractAutowireCapableBeanFactory#createBeanInstance 中會通過反射獲取到Bean的構造器,如果是有參構造就會走autowireConstructor 方法,通過有參構造創建實例
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {// Make sure bean class is actually resolved at this point.Class<?> beanClass = resolveBeanClass(mbd, beanName);...省略...// Need to determine the constructor...Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);if (ctors != null ||mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {//【重要】構造器注入參數return autowireConstructor(beanName, mbd, ctors, args);}// No special handling: simply use no-arg constructor.return instantiateBean(beanName, mbd);}
在autowireConstructor方法中會通過 ConstructorResolver 對構造器參數進行解析
protected BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {//構造器解析器,注入return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);}public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,@Nullable Constructor<?>[] chosenCtors, @Nullable final Object[] explicitArgs) {...省略...else {//得到構造器參數ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();//得到構造器參數值resolvedValues = new ConstructorArgumentValues();//解析參數值【重要】minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);}...省略...try {//實例化策略final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy();Object beanInstance;if (System.getSecurityManager() != null) {final Constructor<?> ctorToUse = constructorToUse;final Object[] argumentsToUse = argsToUse;beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->strategy.instantiate(mbd, beanName, beanFactory, ctorToUse, argumentsToUse),beanFactory.getAccessControlContext());}else {//實例化對象,根據有參構造器,使用反射創建實例beanInstance = strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);}bw.setBeanInstance(beanInstance);return bw;}
resolveConstructorArguments 方法中又通過 BeanDefinitionValueResolver來解析屬性值,有參數的值了,就會走反射,根據有參構造器創建實例返回。
private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();TypeConverter converter = (customConverter != null ? customConverter : bw);//屬性值的解析器BeanDefinitionValueResolver valueResolver =new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);...省略...for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) {if (valueHolder.isConverted()) {resolvedValues.addGenericArgumentValue(valueHolder);}else {//為構造器參數值做解析,這里和之前分析的set注入的屬性值解析就一樣了Object resolvedValue =valueResolver.resolveValueIfNecessary('constructor argument', valueHolder.getValue());ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());resolvedValueHolder.setSource(valueHolder);resolvedValues.addGenericArgumentValue(resolvedValueHolder);}}return minNrOfArgs;}
因為之前 resolveValueIfNecessary方法已經分析過了,這里就不多說了。
總結到這里屬性注入的流程就分析完了,總結都在這個圖上
喜歡的話就給個好評吧,你的肯定是我堅持寫作最大的動力,來吧兄弟們,給我一點動力
以上就是Spring Bean的實例化之屬性注入源碼剖析過程的詳細內容,更多關于Spring Bean 實例化屬性注入的資料請關注好吧啦網其它相關文章!
相關文章: