1. 程式人生 > >Spring-IOC源碼解讀3-依賴註入

Spring-IOC源碼解讀3-依賴註入

dso raw 類型 err ini sum optional ... loader

當容器已經載入了BeanDefinition的信息完成了初始化,我們繼續分析依賴註入的原理,需要註意的是依賴註入是用戶第一次向IOC容器獲取Bean的時候發生的,這裏有個例外,那就是如果用戶在BeanDefinition裏面指定了lazy-init屬性完成預實例化,那麽依賴註入的過程則在初始化過程中完成。在基本的BeanFactory接口中有一個核心的getBean()方法,這裏就是依賴註入發生的地方。
我們從DefaultListAbleBeanFactory的父類AbstarctBeanFactory 入手看看getBean的實現:

public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
        return doGetBean(name, requiredType, null, false);
    }

---------------------------> 進入doGetBean

protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)throws BeansException {

        final String beanName = transformedBeanName(name);
        Object bean;

        // 先從緩存中獲取bean,處理那些已經被創建過的單例的bean,對於這種bean不需要重復創建
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
            if (logger.isDebugEnabled()) {
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.debug("Returning eagerly cached instance of singleton bean ‘" + beanName + "‘ that is not fully initialized yet - a consequence of a circular reference");
                }
                else {
                    logger.debug("Returning cached instance of singleton bean ‘" + beanName + "‘");
                }
            }
            //完成FactoryBean的相關處理,以取得FactoryBean的生產結果
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }

        else {
            // Fail if we‘re already creating this bean instance:
            // We‘re assumably within a circular reference.
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            // 檢查beandefinition是否存在,如果不存在就去父類的BeanFactory中尋找,找不到就沿著雙親BeanFactory一直向上找
            BeanFactory parentBeanFactory = getParentBeanFactory();
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                // Not found -> check parent.
                String nameToLookup = originalBeanName(name);
                if (args != null) {
                    // Delegation to parent with explicit args.
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                }
                else {
                    // No args -> delegate to standard getBean method.
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
            }

            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);
            }
            //根據bean的名字獲取BeanDefinition
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);

            // 獲取當前bean的所有依賴bean,觸發getBean的遞歸調用,直到取得一個沒有任何依賴的bean
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
                for (String dependsOnBean : dependsOn) {
                    getBean(dependsOnBean);
                    registerDependentBean(dependsOnBean, beanName);
                }
            }

            // 創建單例模式的bean的實例,這裏有一個回調函數getObject(),會在getSingleton中調用ObjectBean的createBean()
            if (mbd.isSingleton()) {
                sharedInstance = getSingleton(beanName, new ObjectFactory() {
                    public Object getObject() throws BeansException {
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            // Explicitly remove instance from singleton cache: It might have been put there
                            // eagerly by the creation process, to allow for circular reference resolution.
                            // Also remove any beans that received a temporary reference to the bean.
                            destroySingleton(beanName);
                            throw ex;
                        }
                    }
                });
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }
            //創建prototype類型的bean實例
            else if (mbd.isPrototype()) {
                // It‘s a prototype -> create a new instance.
                Object prototypeInstance = null;
                try {
                    beforePrototypeCreation(beanName);
                    prototypeInstance = createBean(beanName, mbd, args);
                }
                finally {
                    afterPrototypeCreation(beanName);
                }
                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            }

            else {
                String scopeName = mbd.getScope();
                final Scope scope = this.scopes.get(scopeName);
                if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope ‘" + scopeName + "‘");
                }
                try {
                    Object scopedInstance = scope.get(beanName, new ObjectFactory() {
                        public Object getObject() throws BeansException {
                            beforePrototypeCreation(beanName);
                            try {
                                return createBean(beanName, mbd, args);
                            }
                            finally {
                                afterPrototypeCreation(beanName);
                            }
                        }
                    });
                    bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                }
                catch (IllegalStateException ex) {
                    throw new BeanCreationException(beanName,"Scope ‘" + scopeName + "‘ is not active for the current thread; " + "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                            ex);
                }
            }
        }

        // 對創建的bean進行類型檢查,如果沒問題就返回剛剛創建的bean,這裏返回的bean已經是包含了依賴關系的bean
        if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
        return (T) bean;
    }

  

我們詳細的看下依賴註入的過程,getBean是依賴註入的起點,之後會調用AbstartcAutoWireCapableBeanFactory類的createBean()方法。

protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)throws BeanCreationException {

        if (logger.isDebugEnabled()) {
            logger.debug("Creating instance of bean ‘" + beanName + "‘");
        }
        // 判斷需要創建的bean是否可實例化,這個類是否可以通過類加載器加載
        resolveBeanClass(mbd, beanName);

        // Prepare method overrides.
        try {
            mbd.prepareMethodOverrides();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "Validation of method overrides failed", ex);
        }

        try {
            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
//如果bean配置了postProcessor,那麽這裏返回的是一個目標bean的代理實例 Object bean = resolveBeforeInstantiation(beanName, mbd); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } //創建bean Object beanInstance = doCreateBean(beanName, mbd, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean ‘" + beanName + "‘"); } return beanInstance; } --------------------->接著看下doCreateBean()如何生成bean的: protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) { // beanWrapper包裝創建出來的bean BeanWrapper instanceWrapper = null; //如果是singleton,先清除緩存中的bean if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } //創建bean的實例 if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); mbd.postProcessed = true; } } // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isDebugEnabled()) { logger.debug("Eagerly caching bean ‘" + beanName + "‘ to allow for resolving potential circular references"); } addSingletonFactory(beanName, new ObjectFactory() { public Object getObject() throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); } // 這裏是對bean的初始化,依賴註入往往在這裏發生,這個exposedObject 在初始化處理完後會返回作為依賴註入到完成後的bean Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { 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); } } if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name ‘" + beanName + "‘ has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "‘getBeanNamesOfType‘ with the ‘allowEagerInit‘ flag turned off, for example."); } } } } // Register bean as disposable. try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }

這裏我麽可以看到與依賴註入密切相關的方法有createBeanInstance和populateBean。在createBeanInstance方法中生成了bean所包含的java對象,這個對象的生成有多種方式,可以通過工廠方法生成,也可以通過autowire特性生成,這些生成方式都是由BeanDefinition指定的,

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
        // 確保需創建的bean的類已經解析
        Class beanClass = resolveBeanClass(mbd, beanName);

        if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Bean class isn‘t public, and non-public access not allowed: " + beanClass.getName());
        }
//使用工廠方法實例化bean
        if (mbd.getFactoryMethodName() != null)  {
            return instantiateUsingFactoryMethod(beanName, mbd, args);
        }

        // Shortcut when re-creating the same bean...
        boolean resolved = false;
        boolean autowireNecessary = false;
        if (args == null) {
            synchronized (mbd.constructorArgumentLock) {
                if (mbd.resolvedConstructorOrFactoryMethod != null) {
                    resolved = true;
                    autowireNecessary = mbd.constructorArgumentsResolved;
                }
            }
        }
        if (resolved) {
            if (autowireNecessary) {
                return autowireConstructor(beanName, mbd, null, null);
            }
            else {
                return instantiateBean(beanName, mbd);
            }
        }

        // 使用構造函數實例化...
        Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        if (ctors != null ||
                mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
                mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
            return autowireConstructor(beanName, mbd, ctors, args);
        }

        // 使用默認的構造函數實例化bean
        return instantiateBean(beanName, mbd);
    }

-----------------------------------> 進入instantiateBean方法

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
        try {
            Object beanInstance;
            final BeanFactory parent = this;
            if (System.getSecurityManager() != null) {
                beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
                    public Object run() {
                        return getInstantiationStrategy().instantiate(mbd, beanName, parent);
                    }
                }, getAccessControlContext());
            }
            else {
//使用默認的實例化策略對bean實例化,默認策略是CGLIB實例化
                beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
            }
            BeanWrapper bw = new BeanWrapperImpl(beanInstance);
            initBeanWrapper(bw);
            return bw;
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
        }
    }

上面的代碼使用SimpleInstantiationStrategy類的instantiate()方法實例化bean,SimpleInstantiationStrategy是Spring生成Bean對象的默認類,這個類提供了兩種實現對象實例化的方法,一種是BeanUtis,它使用了JVM的反射功能,另一種通過CGLIB實現:

public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
        // Don‘t override the class with CGLIB if no overrides.
        if (beanDefinition.getMethodOverrides().isEmpty()) {
            //取得指定的構造方法或者生成對象的工廠方法來對bean實例化
            Constructor<?> constructorToUse;
            synchronized (beanDefinition.constructorArgumentLock) {
                constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod;
                if (constructorToUse == null) {
                    final Class clazz = beanDefinition.getBeanClass();
                    if (clazz.isInterface()) {
                        throw new BeanInstantiationException(clazz, "Specified class is an interface");
                    }
                    try {
                        if (System.getSecurityManager() != null) {
                            constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor>() {
                                public Constructor run() throws Exception {
                                    return clazz.getDeclaredConstructor((Class[]) null);
                                }
                            });
                        }
                        else {
                            constructorToUse =  clazz.getDeclaredConstructor((Class[]) null);
                        }
                        beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;
                    }
                    catch (Exception ex) {
                        throw new BeanInstantiationException(clazz, "No default constructor found", ex);
                    }
                }
            }
            //使用beanUtils實例化
            return BeanUtils.instantiateClass(constructorToUse);
        }
        else {
            // 使用CGLIB實例化
            return instantiateWithMethodInjection(beanDefinition, beanName, owner);
        }
    }

我們的測試代碼是使用BeanUtils完成的bean實例化,BeanUtils裏面就是使用了JVM的反射調用構造方法實例化的bean。具體的bean的實例化過程到這裏已經完成了。下面我們再看下Spring是怎麽設置這些對象的依賴關系的。這個過程涉及對各種bean屬性的處理,現在我們回到之前的另一個重要的方法populateBean。

protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) {
        //取得BeanDefinition設置的property
        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;
                    if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                        continueWithPropertyPopulation = false;
                        break;
                    }
                }
            }
        }

        if (!continueWithPropertyPopulation) {
            return;
        }
        //開始依賴註入,先處理autowire的註入
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
                mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
            MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

            // 根據名字註入
            if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
                autowireByName(beanName, mbd, bw, newPvs);
            }

            // 根據類型註入
            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);
            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);
            }
        }
        //對屬性進行註入
        applyPropertyValues(beanName, mbd, bw, pvs);
    }

具體的屬性註入過程:

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;
            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 {
            original = Arrays.asList(pvs.getPropertyValues());
        }

        TypeConverter converter = getCustomTypeConverter();
        if (converter == null) {
            converter = bw;
        }
       //創建BeanDefinitionResolver解析BeanDefinition
        BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

        //為解析值創建一個副本,副本的數據將會註入到bean中
        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();
        }

        // 依賴註入發生的地方,會在BeanWrapperImpl中完成
        try {
            bw.setPropertyValues(new MutablePropertyValues(deepCopy));
        }
        catch (BeansException ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", ex);
        }
    }

看一下BeanDefinitionResolver如何解析BeanDefinition的,以對Reference的解析為例,對RuntimeBeanReference類型的註入在resolveReference中,:

private Object resolveReference(Object argName, RuntimeBeanReference ref) {
        try {
            //從runtimeReference中取得ref的名字,這個runtimeReference是在載入的過程中根據配置生成的
            String refName = ref.getBeanName();
            refName = String.valueOf(evaluate(refName));
            //如果ref在父類就去父類獲取
            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");
                }
                return this.beanFactory.getParentBeanFactory().getBean(refName);
            }
            //在當前容器獲取bean,觸發getBean,如果依賴註入沒發生,這裏會觸發響應的依賴註入發生
            else {
                Object bean = this.beanFactory.getBean(refName);
                this.beanFactory.registerDependentBean(refName, this.beanName);
                return bean;
            }
        }
        catch (BeansException ex) {
            throw new BeanCreationException(
                    this.beanDefinition.getResourceDescription(), this.beanName,
                    "Cannot resolve reference to bean ‘" + ref.getBeanName() + "‘ while setting " + argName, ex);
        }
    }

再看下其他類型的屬性註入,比如List

private List resolveManagedList(Object argName, List<?> ml) {
        List<Object> resolved = new ArrayList<Object>(ml.size());
        for (int i = 0; i < ml.size(); i++) {
            resolved.add(
                resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));
        }
        return resolved;
    }

---------------------------> 進入resolveValueIfNecessary方法

public Object resolveValueIfNecessary(Object argName, 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) {
            RuntimeBeanReference ref = (RuntimeBeanReference) value;
            return resolveReference(argName, ref);
        }
        else if (value instanceof RuntimeBeanNameReference) {
            String refName = ((RuntimeBeanNameReference) value).getBeanName();
            refName = String.valueOf(evaluate(refName));
            if (!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 bdHolder = (BeanDefinitionHolder) value;
            return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
        }
        else if (value instanceof BeanDefinition) {
            // Resolve plain BeanDefinition, without contained name: use dummy name.
            BeanDefinition bd = (BeanDefinition) value;
            return resolveInnerBean(argName, "(inner bean)", bd);
        }
        //對Array進行解析
        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);
        }
        //對List進行解析
        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();
            for (Map.Entry propEntry : original.entrySet()) {
                Object propKey = propEntry.getKey();
                Object propValue = propEntry.getValue();
                if (propKey instanceof TypedStringValue) {
                    propKey = evaluate((TypedStringValue) propKey);
                }
                if (propValue instanceof TypedStringValue) {
                    propValue = evaluate((TypedStringValue) propValue);
                }
                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 {
                    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 {
            return evaluate(value);
        }
    }

完成這個解析過程後,已經為bean的依賴註入準備好了條件,這裏是真正把bean對象設置到它所依賴的另一個對象中去的地方,其中屬性的處理也是各種各樣的,依賴註入的發生是在BeanWrapper的setPropertyValue中,具體的完成確是在BeanWrapper的子類BeanWrapperImpl中,代碼如下:

private void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {
        String propertyName = tokens.canonicalName;
        String actualName = tokens.actualName;

        if (tokens.keys != null) {
            // 設置tokens的索引和keys
            PropertyTokenHolder getterTokens = new PropertyTokenHolder();
            getterTokens.canonicalName = tokens.canonicalName;
            getterTokens.actualName = tokens.actualName;
            getterTokens.keys = new String[tokens.keys.length - 1];
            System.arraycopy(tokens.keys, 0, getterTokens.keys, 0, tokens.keys.length - 1);
            Object propValue;
            try {
                //取得bean中對註入對象的引用,比如Array,List,Set,Map等
                propValue = getPropertyValue(getterTokens);
            }
            catch (NotReadablePropertyException ex) {
                throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,"Cannot access indexed value in property referenced " +"in indexed property path ‘" + propertyName + "‘", ex);
            }
            // Set value for last key.
            String key = tokens.keys[tokens.keys.length - 1];
            if (propValue == null) {
                throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + propertyName, "Cannot access indexed value in property referenced " + "in indexed property path ‘" + propertyName + "‘: returned null");
            }
            //對Array進行註入
            else if (propValue.getClass().isArray()) {
                PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
                Class requiredType = propValue.getClass().getComponentType();
                int arrayIndex = Integer.parseInt(key);
                Object oldValue = null;
                try {
                    if (isExtractOldValueForEditor()) {
                        oldValue = Array.get(propValue, arrayIndex);
                    }
                    Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(), requiredType, new PropertyTypeDescriptor(pd, new MethodParameter(pd.getReadMethod(), -1), requiredType));
                    Array.set(propValue, arrayIndex, convertedValue);
                }
                catch (IndexOutOfBoundsException ex) {
                    throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,"Invalid array index in property path ‘" + propertyName + "‘", ex);
                }
            }
            //對List進行註入
            else if (propValue instanceof List) {
                PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
                Class requiredType = GenericCollectionTypeResolver.getCollectionReturnType(pd.getReadMethod(), tokens.keys.length);
                List list = (List) propValue;
                int index = Integer.parseInt(key);
                Object oldValue = null;
                if (isExtractOldValueForEditor() && index < list.size()) {
                    oldValue = list.get(index);
                }
                Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(), requiredType, new PropertyTypeDescriptor(pd, new MethodParameter(pd.getReadMethod(), -1), requiredType));
                if (index < list.size()) {
                    list.set(index, convertedValue);
                }
                else if (index >= list.size()) {
                    for (int i = list.size(); i < index; i++) {
                        try {
                            list.add(null);
                        }
                        catch (NullPointerException ex) {
                            throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,"Cannot set element with index " + index + " in List of size " +list.size() + ", accessed using property path ‘" + propertyName + "‘: List does not support filling up gaps with null elements");
                        }
                    }
                    list.add(convertedValue);
                }
            }
            //對Map進行註入
            else if (propValue instanceof Map) {
                PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
                Class mapKeyType = GenericCollectionTypeResolver.getMapKeyReturnType(pd.getReadMethod(), tokens.keys.length);
                Class mapValueType = GenericCollectionTypeResolver.getMapValueReturnType(pd.getReadMethod(), tokens.keys.length);
                Map map = (Map) propValue;
                // IMPORTANT: Do not pass full property name in here - property editors
                // must not kick in for map keys but rather only for map values.
                Object convertedMapKey = convertIfNecessary(null, null, key, mapKeyType,new PropertyTypeDescriptor(pd, new MethodParameter(pd.getReadMethod(), -1), mapKeyType));
                Object oldValue = null;
                if (isExtractOldValueForEditor()) {
                    oldValue = map.get(convertedMapKey);
                }
                // Pass full property name and old value in here, since we want full
                // conversion ability for map values.
                Object convertedMapValue = convertIfNecessary(popertyName, oldValue, pv.getValue(), mapValueType,new TypeDescriptor(new MethodParameter(pd.getReadMethod(), -1, tokens.keys.length + 1)));
                map.put(convertedMapKey, convertedMapValue);
            }
            else {
                throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,"Property referenced in indexed property path ‘" + propertyName +"‘ is neither an array nor a List nor a Map; returned value was [" + pv.getValue() + "]");
            }
        }
        //對非集合類的變量進行註入
        else {
            PropertyDescriptor pd = pv.resolvedDescriptor;
            if (pd == null || !pd.getWriteMethod().getDeclaringClass().isInstance(this.object)) {
                pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
                if (pd == null || pd.getWriteMethod() == null) {
                    if (pv.isOptional()) {
                        logger.debug("Ignoring optional value for property ‘" + actualName + "‘ - property not found on bean class [" + getRootClass().getName() + "]");
                        return;
                    }
                    else {
                        PropertyMatches matches = PropertyMatches.forProperty(propertyName, getRootClass());
                        throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,matches.buildErrorMessage(), matches.getPossibleMatches());
                    }
                }
                pv.getOriginalPropertyValue().resolvedDescriptor = pd;
            }

            Object oldValue = null;
            try {
                Object originalValue = pv.getValue();
                Object valueToApply = originalValue;
                if (!Boolean.FALSE.equals(pv.conversionNecessary)) {
                    if (pv.isConverted()) {
                        valueToApply = pv.getConvertedValue();
                    }
                    else {
                        if (isExtractOldValueForEditor() && pd.getReadMethod() != null) {
                            final Method readMethod = pd.getReadMethod();
                            if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers()) && !readMethod.isAccessible()) {
                                if (System.getSecurityManager()!= null) {
                                    AccessController.doPrivileged(new PrivilegedAction<Object>() {
                                        public Object run() {
                                            readMethod.setAccessible(true);
                                            return null;
                                        }
                                    });
                                }
                                else {
                                    readMethod.setAccessible(true);
                                }
                            }
                            try {
                                if (System.getSecurityManager() != null) {
                                    oldValue = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                                        public Object run() throws Exception {
                                            return readMethod.invoke(object);
                                        }
                                    }, acc);
                                }
                                else {
                                    oldValue = readMethod.invoke(object);
                                }
                            }
                            catch (Exception ex) {
                                if (ex instanceof PrivilegedActionException) {
                                    ex = ((PrivilegedActionException) ex).getException();
                                }
                                if (logger.isDebugEnabled()) {
                                    logger.debug("Could not read previous value of property ‘" + this.nestedPath + propertyName + "‘", ex);
                                }
                            }
                        }
                        valueToApply = convertForProperty(propertyName, oldValue, originalValue, pd);
                    }
                    pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
                }
                //取得註入屬性的set方法通過反射機制註入對象
                final Method writeMethod = (pd instanceof GenericTypeAwarePropertyDescriptor ?  ((GenericTypeAwarePropertyDescriptor) pd).getWriteMethodForActualAccess() : pd.getWriteMethod());
                if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers()) && !writeMethod.isAccessible()) {
                    if (System.getSecurityManager()!= null) {
                        AccessController.doPrivileged(new PrivilegedAction<Object>() {
                            public Object run() {
                                writeMethod.setAccessible(true);
                                return null;
                            }
                        });
                    }
                    else {
                        writeMethod.setAccessible(true);
                    }
                }
                final Object value = valueToApply;
                if (System.getSecurityManager() != null) {
                    try {
                        AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                            public Object run() throws Exception {
                                writeMethod.invoke(object, value);
                                return null;
                            }
                        }, acc);
                    }
                    catch (PrivilegedActionException ex) {
                        throw ex.getException();
                    }
                }
                else {
                    writeMethod.invoke(this.object, value);
                }
            }
            catch (TypeMismatchException ex) {
                throw ex;
            }
            catch (InvocationTargetException ex) {
                PropertyChangeEvent propertyChangeEvent =  new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
                if (ex.getTargetException() instanceof ClassCastException) {
                    throw new TypeMismatchException(propertyChangeEvent, pd.getPropertyType(), ex.getTargetException());
                }
                else {
                    throw new MethodInvocationException(propertyChangeEvent, ex.getTargetException());
                }
            }
            catch (Exception ex) {
                PropertyChangeEvent pce =  new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
                throw new MethodInvocationException(pce, ex);
            }
        }
    }

通過上面的分析就完成了對bean屬性的註入。在bean的創建和對象的依賴註入過程中,需要根據BeanDefinition中的信息來遞歸的完成依賴註入,這些遞歸都是以getBean()為入口的,一個遞歸是上下文體系中查找需要的bean和創建bean的遞歸調用;另一個遞歸是在依賴註入的時候通過遞歸調用容器的getBean方法得到當前Bean的依賴Bean同是觸發對依賴bean的創建和依賴註入。在對Bean的屬性進行依賴註入的時候解析的過程也是一個遞歸的過程。這樣根據依賴關系一層一層的完成bean的創建和註入,直到最後完成Bean的創建,有了這個頂層Bean的創建和對它的依賴註入的完成意味著和當前Bean相關的整個依賴鏈的完成。

Spring-IOC源碼解讀3-依賴註入