zoukankan      html  css  js  c++  java
  • Spring-IOC源码解读3-依赖注入

    当容器已经载入了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相关的整个依赖链的完成。

  • 相关阅读:
    Codeforces Global Round 17
    [UER #6] 逃跑
    [模板] 一般图最大匹配
    Codeforces Global Round 18
    Flash/Flex学习笔记(50):3D线条与填充
    Flash/Flex学习笔记(47):反向运动学(上)
    Flash/Flex学习笔记(46):正向运动学
    Flash/Flex学习笔记(49):3D基础
    Flash/Flex学习笔记(51):3维旋转与透视变换(PerspectiveProjection)
    Flash/Flex学习笔记(54):迷你滚动条ScrollBar
  • 原文地址:https://www.cnblogs.com/pepper7/p/7671213.html
Copyright © 2011-2022 走看看