spring IOC 依赖注入 下

本文详细介绍了Spring框架中Bean依赖注入的过程,包括属性值获取、自动装配、依赖检查及属性值设置等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

摘要

上一篇博客 spring IOC 依赖注入,看到了整个实例化Bean的过程,通过反射或者cglib增强实例化Bean。但此时对bean之间的依赖关系,属性的处理还未发生。这些将在populateBean中实现。

本文概述

依赖关系处理处理的依据是BeanDefinition

正文

    protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
        //从BeanDefinition中获得属性值。
        PropertyValues pvs = mbd.getPropertyValues();
        if (bw == null) {
            if (!((PropertyValues)pvs).isEmpty()) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
            }
        } else {
            boolean continueWithPropertyPopulation = true;
            if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
                Iterator var6 = this.getBeanPostProcessors().iterator();

                while(var6.hasNext()) {
                    BeanPostProcessor bp = (BeanPostProcessor)var6.next();
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                        if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                            continueWithPropertyPopulation = false;
                            break;
                        }
                    }
                }
            }
            //对自动装配的注入
            if (continueWithPropertyPopulation) {
                if (mbd.getResolvedAutowireMode() == 1 || mbd.getResolvedAutowireMode() == 2) {
                    MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
                    if (mbd.getResolvedAutowireMode() == 1) {
                        this.autowireByName(beanName, mbd, bw, newPvs);
                    }

                    if (mbd.getResolvedAutowireMode() == 2) {
                        this.autowireByType(beanName, mbd, bw, newPvs);
                    }

                    pvs = newPvs;
                }

                boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
                boolean needsDepCheck = mbd.getDependencyCheck() != 0;
                if (hasInstAwareBpps || needsDepCheck) {
                    PropertyDescriptor[] filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                    if (hasInstAwareBpps) {
                        Iterator var9 = this.getBeanPostProcessors().iterator();

                        while(var9.hasNext()) {
                            BeanPostProcessor bp = (BeanPostProcessor)var9.next();
                            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                                pvs = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
                                if (pvs == null) {
                                    return;
                                }
                            }
                        }
                    }

                    if (needsDepCheck) {
                        this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
                    }
                }
                //对属性的注入
                this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
            }
        }
    }

applyPropertyValues

    protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
        if (pvs != null && !pvs.isEmpty()) {
            MutablePropertyValues mpvs = null;
            if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
                ((BeanWrapperImpl)bw).setSecurityContext(this.getAccessControlContext());
            }

            List original;
            if (pvs instanceof MutablePropertyValues) {
                mpvs = (MutablePropertyValues)pvs;
                if (mpvs.isConverted()) {
                    try {
                        bw.setPropertyValues(mpvs);
                        return;
                    } catch (BeansException var18) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", var18);
                    }
                }

                original = mpvs.getPropertyValueList();
            } else {
                original = Arrays.asList(pvs.getPropertyValues());
            }

            TypeConverter converter = this.getCustomTypeConverter();
            if (converter == null) {
                converter = bw;
            }

            BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, (TypeConverter)converter);
            List<PropertyValue> deepCopy = new ArrayList(original.size());
            boolean resolveNecessary = false;
            Iterator var11 = original.iterator();

            while(true) {
                while(var11.hasNext()) {
                    PropertyValue pv = (PropertyValue)var11.next();
                    if (pv.isConverted()) {
                        deepCopy.add(pv);
                    } else {
                        String propertyName = pv.getName();
                        Object originalValue = pv.getValue();
                        //对BeanDefinition的解析
                        Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
                        Object convertedValue = resolvedValue;
                        boolean convertible = bw.isWritableProperty(propertyName) && !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
                        if (convertible) {
                            convertedValue = this.convertForProperty(resolvedValue, propertyName, bw, (TypeConverter)converter);
                        }

                        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();
                }

                try {
                    bw.setPropertyValues(new MutablePropertyValues(deepCopy));
                    return;
                } catch (BeansException var19) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", var19);
                }
            }
        }
    }

valueResolver.resolveValueIfNecessary(pv, originalValue)中完成了各种解析

    public Object resolveValueIfNecessary(Object argName, Object value) {
        if (value instanceof RuntimeBeanReference) {
            RuntimeBeanReference ref = (RuntimeBeanReference)value;
            return this.resolveReference(argName, ref);
        } else if (value instanceof RuntimeBeanNameReference) {
            String refName = ((RuntimeBeanNameReference)value).getBeanName();
            refName = String.valueOf(this.doEvaluate(refName));
            if (!this.beanFactory.containsBean(refName)) {
                throw new BeanDefinitionStoreException("Invalid bean name '" + refName + "' in bean reference for " + argName);
            } else {
                return refName;
            }
        } else if (value instanceof BeanDefinitionHolder) {
            BeanDefinitionHolder bdHolder = (BeanDefinitionHolder)value;
            return this.resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
        } else if (value instanceof BeanDefinition) {
            BeanDefinition bd = (BeanDefinition)value;
            String innerBeanName = "(inner bean)#" + ObjectUtils.getIdentityHexString(bd);
            return this.resolveInnerBean(argName, innerBeanName, bd);
        } else if (value instanceof ManagedArray) {
            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 var9) {
                        throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Error resolving array type for " + argName, var9);
                    }
                } else {
                    elementType = Object.class;
                }
            }

            return this.resolveManagedArray(argName, (List)value, elementType);
        } else if (value instanceof ManagedList) {
            return this.resolveManagedList(argName, (List)value);
        } else if (value instanceof ManagedSet) {
            return this.resolveManagedSet(argName, (Set)value);
        } else if (value instanceof ManagedMap) {
            return this.resolveManagedMap(argName, (Map)value);
        } else if (value instanceof ManagedProperties) {
            Properties original = (Properties)value;
            Properties copy = new Properties();

            Object propKey;
            Object propValue;
            for(Iterator var19 = original.entrySet().iterator(); var19.hasNext(); copy.put(propKey, propValue)) {
                Entry<Object, Object> propEntry = (Entry)var19.next();
                propKey = propEntry.getKey();
                propValue = propEntry.getValue();
                if (propKey instanceof TypedStringValue) {
                    propKey = this.evaluate((TypedStringValue)propKey);
                }

                if (propValue instanceof TypedStringValue) {
                    propValue = this.evaluate((TypedStringValue)propValue);
                }
            }

            return copy;
        } else if (value instanceof TypedStringValue) {
            TypedStringValue typedStringValue = (TypedStringValue)value;
            Object valueObject = this.evaluate(typedStringValue);

            try {
                Class<?> resolvedTargetType = this.resolveTargetType(typedStringValue);
                return resolvedTargetType != null ? this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType) : valueObject;
            } catch (Throwable var10) {
                throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Error converting typed String value for " + argName, var10);
            }
        } else {
            return this.evaluate(value);
        }
    }
    private Object resolveReference(Object argName, RuntimeBeanReference ref) {
        try {
            String refName = ref.getBeanName();
            refName = String.valueOf(this.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");
                } else {
                    //如果ref在双亲ioc容器中,这触发对ioc双亲容器的getBean
                    return this.beanFactory.getParentBeanFactory().getBean(refName);
                }
            } else {
                Object bean = this.beanFactory.getBean(refName);
                this.beanFactory.registerDependentBean(refName, this.beanName);
                return bean;
            }
        } catch (BeansException var5) {
            throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, var5);
        }
    }

在完成解析后为依赖注入做好了准备
bw.setPropertyValues(new MutablePropertyValues(deepCopy));

    public 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());
        Iterator var6 = propertyValues.iterator();

        while(var6.hasNext()) {
            PropertyValue pv = (PropertyValue)var6.next();

            try {
                this.setPropertyValue(pv);
            } catch (NotWritablePropertyException var9) {
                if (!ignoreUnknown) {
                    throw var9;
                }
            } catch (NullValueInNestedPathException var10) {
                if (!ignoreInvalid) {
                    throw var10;
                }
            } catch (PropertyAccessException var11) {
                if (propertyAccessExceptions == null) {
                    propertyAccessExceptions = new LinkedList();
                }

                propertyAccessExceptions.add(var11);
            }
        }

        if (propertyAccessExceptions != null) {
            PropertyAccessException[] paeArray = (PropertyAccessException[])propertyAccessExceptions.toArray(new PropertyAccessException[propertyAccessExceptions.size()]);
            throw new PropertyBatchUpdateException(paeArray);
        }
    }

this.setPropertyValue(pv);

    public void setPropertyValue(PropertyValue pv) throws BeansException {
        AbstractNestablePropertyAccessor.PropertyTokenHolder tokens = (AbstractNestablePropertyAccessor.PropertyTokenHolder)pv.resolvedTokens;
        if (tokens == null) {
            String propertyName = pv.getName();

            AbstractNestablePropertyAccessor nestedPa;
            try {
                nestedPa = this.getPropertyAccessorForPropertyPath(propertyName);
            } catch (NotReadablePropertyException var6) {
                throw new NotWritablePropertyException(this.getRootClass(), this.nestedPath + propertyName, "Nested property in path '" + propertyName + "' does not exist", var6);
            }

            tokens = this.getPropertyNameTokens(this.getFinalPath(nestedPa, propertyName));
            if (nestedPa == this) {
                pv.getOriginalPropertyValue().resolvedTokens = tokens;
            }

            nestedPa.setPropertyValue(tokens, pv);
        } else {
            this.setPropertyValue(tokens, pv);
        }

    }

propValue = this.getPropertyValue(getterTokens); 循环取得各种类型对象的引用

   protected Object getPropertyValue(AbstractNestablePropertyAccessor.PropertyTokenHolder tokens) throws BeansException {
        String propertyName = tokens.canonicalName;
        String actualName = tokens.actualName;
        AbstractNestablePropertyAccessor.PropertyHandler ph = this.getLocalPropertyHandler(actualName);
        if (ph != null && ph.isReadable()) {
            try {
                Object value = ph.getValue();
                if (tokens.keys != null) {
                    if (value == null) {
                        if (!this.isAutoGrowNestedPaths()) {
                            throw new NullValueInNestedPathException(this.getRootClass(), this.nestedPath + propertyName, "Cannot access indexed value of property referenced in indexed property path '" + propertyName + "': returned null");
                        }

                        value = this.setDefaultValue(tokens.actualName);
                    }

                    String indexedPropertyName = tokens.actualName;

                    for(int i = 0; i < tokens.keys.length; ++i) {
                        String key = tokens.keys[i];
                        if (value == null) {
                            throw new NullValueInNestedPathException(this.getRootClass(), this.nestedPath + propertyName, "Cannot access indexed value of property referenced in indexed property path '" + propertyName + "': returned null");
                        }

                        int index;
                        if (value.getClass().isArray()) {
                            index = Integer.parseInt(key);
                            value = this.growArrayIfNecessary(value, index, indexedPropertyName);
                            value = Array.get(value, index);
                        } else if (value instanceof List) {
                            index = Integer.parseInt(key);
                            List<Object> list = (List)value;
                            this.growCollectionIfNecessary(list, index, indexedPropertyName, ph, i + 1);
                            value = list.get(index);
                        } else if (value instanceof Set) {
                            Set<Object> set = (Set)value;
                            int index = Integer.parseInt(key);
                            if (index < 0 || index >= set.size()) {
                                throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + propertyName, "Cannot get element with index " + index + " from Set of size " + set.size() + ", accessed using property path '" + propertyName + "'");
                            }

                            Iterator<Object> it = set.iterator();

                            for(int j = 0; it.hasNext(); ++j) {
                                Object elem = it.next();
                                if (j == index) {
                                    value = elem;
                                    break;
                                }
                            }
                        } else {
                            if (!(value instanceof Map)) {
                                throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + propertyName, "Property referenced in indexed property path '" + propertyName + "' is neither an array nor a List nor a Set nor a Map; returned value was [" + value + "]");
                            }

                            Map<Object, Object> map = (Map)value;
                            Class<?> mapKeyType = ph.getResolvableType().getNested(i + 1).asMap().resolveGeneric(new int[]{0});
                            TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(mapKeyType);
                            Object convertedMapKey = this.convertIfNecessary((String)null, (Object)null, key, mapKeyType, typeDescriptor);
                            value = map.get(convertedMapKey);
                        }

                        indexedPropertyName = indexedPropertyName + "[" + key + "]";
                    }
                }

                return value;
            } catch (IndexOutOfBoundsException var14) {
                throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + propertyName, "Index of out of bounds in property path '" + propertyName + "'", var14);
            } catch (NumberFormatException var15) {
                throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + propertyName, "Invalid index in property path '" + propertyName + "'", var15);
            } catch (TypeMismatchException var16) {
                throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + propertyName, "Invalid index in property path '" + propertyName + "'", var16);
            } catch (InvocationTargetException var17) {
                throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + propertyName, "Getter for property '" + actualName + "' threw exception", var17);
            } catch (Exception var18) {
                throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + propertyName, "Illegal attempt to get property '" + actualName + "' threw exception", var18);
            }
        } else {
            throw new NotReadablePropertyException(this.getRootClass(), this.nestedPath + propertyName);
        }
    }

判断取得的引用是什么类型,并注入到其中

private void processKeyedProperty(AbstractNestablePropertyAccessor.PropertyTokenHolder tokens, PropertyValue pv) {
        Object propValue = this.getPropertyHoldingValue(tokens);
        String lastKey = tokens.keys[tokens.keys.length - 1];
        AbstractNestablePropertyAccessor.PropertyHandler ph;
        Class requiredType;
        Object convertedValue;
        Object newArray;
        if (propValue.getClass().isArray()) {
            ph = this.getLocalPropertyHandler(tokens.actualName);
            requiredType = propValue.getClass().getComponentType();
            int arrayIndex = Integer.parseInt(lastKey);
            Object oldValue = null;

            try {
                if (this.isExtractOldValueForEditor() && arrayIndex < Array.getLength(propValue)) {
                    oldValue = Array.get(propValue, arrayIndex);
                }

                convertedValue = this.convertIfNecessary(tokens.canonicalName, oldValue, pv.getValue(), requiredType, ph.nested(tokens.keys.length));
                int length = Array.getLength(propValue);
                if (arrayIndex >= length && arrayIndex < this.autoGrowCollectionLimit) {
                    Class<?> componentType = propValue.getClass().getComponentType();
                    newArray = Array.newInstance(componentType, arrayIndex + 1);
                    System.arraycopy(propValue, 0, newArray, 0, length);
                    this.setPropertyValue(tokens.actualName, newArray);
                    propValue = this.getPropertyValue(tokens.actualName);
                }

                Array.set(propValue, arrayIndex, convertedValue);
            } catch (IndexOutOfBoundsException var16) {
                throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + tokens.canonicalName, "Invalid array index in property path '" + tokens.canonicalName + "'", var16);
            }
        } else {
            Object convertedValue;
            if (propValue instanceof List) {
                ph = this.getPropertyHandler(tokens.actualName);
                requiredType = ph.getCollectionType(tokens.keys.length);
                List<Object> list = (List)propValue;
                int index = Integer.parseInt(lastKey);
                convertedValue = null;
                if (this.isExtractOldValueForEditor() && index < list.size()) {
                    convertedValue = list.get(index);
                }

                convertedValue = this.convertIfNecessary(tokens.canonicalName, convertedValue, pv.getValue(), requiredType, ph.nested(tokens.keys.length));
                int size = list.size();
                if (index >= size && index < this.autoGrowCollectionLimit) {
                    for(int i = size; i < index; ++i) {
                        try {
                            list.add((Object)null);
                        } catch (NullPointerException var15) {
                            throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + tokens.canonicalName, "Cannot set element with index " + index + " in List of size " + size + ", accessed using property path '" + tokens.canonicalName + "': List does not support filling up gaps with null elements");
                        }
                    }

                    list.add(convertedValue);
                } else {
                    try {
                        list.set(index, convertedValue);
                    } catch (IndexOutOfBoundsException var14) {
                        throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + tokens.canonicalName, "Invalid list index in property path '" + tokens.canonicalName + "'", var14);
                    }
                }
            } else {
                if (!(propValue instanceof Map)) {
                    throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + tokens.canonicalName, "Property referenced in indexed property path '" + tokens.canonicalName + "' is neither an array nor a List nor a Map; returned value was [" + propValue + "]");
                }

                ph = this.getLocalPropertyHandler(tokens.actualName);
                requiredType = ph.getMapKeyType(tokens.keys.length);
                Class<?> mapValueType = ph.getMapValueType(tokens.keys.length);
                Map<Object, Object> map = (Map)propValue;
                TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(requiredType);
                convertedValue = this.convertIfNecessary((String)null, (Object)null, lastKey, requiredType, typeDescriptor);
                Object oldValue = null;
                if (this.isExtractOldValueForEditor()) {
                    oldValue = map.get(convertedValue);
                }

                newArray = this.convertIfNecessary(tokens.canonicalName, oldValue, pv.getValue(), mapValueType, ph.nested(tokens.keys.length));
                map.put(convertedValue, newArray);
            }
        }

    }

到此,依赖注入完成

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值