spring 源码解读-DI

spring 源码解读-DI

一、DI 发生的时间

当SpringIOC容器完成了Bean定义资源的定位、加载、解析、注册之后,IOC容器中已经管理类的Bean定义的相关数据,但是这个时候IOC容器还没有对所管理的Bean进行依赖注入。依赖注入发生的时间:

  1. 第一次getBean()方法时,IOC触发依赖注入;
  2. 当配置文件中将bean 元素配置了lazy-init = false 属性,即让容器在解析注册bean定义时进行实例化,触发依赖注入。

BeanFactory 接口定义了Spring IOC 容器基本功能和规范,BeanFactory 接口定义了几个getBean()方法。

二、getBean()触发依赖注入

在BeanFactory 中可以看到getBean()方法,它具体的实现在AbstractBeanFactory 中。

1、寻找getBean入口

  public Object getBean(String name) throws BeansException {
        return this.doGetBean(name, (Class)null, (Object[])null, false);
    }
 protected <T> T doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly) 
 throws BeansException {
        //根据指定名称获取被管理的bean的名称
        //如果指定别名,将别名转换成规范的bean的名称
        final String beanName = this.transformedBeanName(name);

        //先从缓存中取是否已经有被创建过的单例类型的bean
        //对应单例的bean,整个IOC容器只需要创建一次
        Object sharedInstance = this.getSingleton(beanName);
        Object bean;
        //IOC容器创建单例bean的实例
        if (sharedInstance != null && args == null) {
            if (this.logger.isDebugEnabled()) {
                //指定的名称的bean,已经有被创建过的单例类型的bean,直接返回已经创建的bean
                if (this.isSingletonCurrentlyInCreation(beanName)) {
                    this.logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
                } else {
                    this.logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
                }
            }

            //获取bean的实例对象,主要是完成FactoryBean的相关处理
            //FactoryBean是创建对象的工厂bean,而BeanFactory是管理容器中Bean的工厂
            bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
        } else {//缓存中没有创建过的单例类型的bean
        
            //缓存中已经有创建过的原型模式bean
            //但是由于循环引用问题,导致实例化对象失败
            if (this.isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            //对IOC容器中是否存在指定名称的BeanDefinition进行检查,先检查当前BeanFactory 中获取所需要的Bean,如果没有则
            //当前容器的父容器去查找,如果还是没有则继续向上查找。
            BeanFactory parentBeanFactory = this.getParentBeanFactory();
            //当前容器的父容器存在,并且当前容器不存在指定名称的bean
            if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
                String nameToLookup = this.originalBeanName(name);
                if (args != null) {
                    return parentBeanFactory.getBean(nameToLookup, args);
                }

               //委派父容器查找
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }

            //创建bean是否需要进行类型验证
            if (!typeCheckOnly) {
                this.markBeanAsCreated(beanName);
            }

            try {
                //根据指定的bean名称获取其父级的bean的定义,主要是解决继承时子类合并父类公共属性
                final RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
                this.checkMergedBeanDefinition(mbd, beanName, args);
                //获取当前bean所依赖的bean
                String[] dependsOn = mbd.getDependsOn();
                String[] var11;
                //如果当前bean有依赖的bean
                if (dependsOn != null) {
                    var11 = dependsOn;
                    int var12 = dependsOn.length;

                    for(int var13 = 0; var13 < var12; ++var13) {
                        String dependsOnBean = var11[var13];
                        if (this.isDependent(beanName, dependsOnBean)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName, 
                            "Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
                        }

                        //递归调用getBean方法,获取当前bean的依赖bean
                        this.registerDependentBean(dependsOnBean, beanName);
                        //当被依赖的bean注册给当前依赖的bean
                        this.getBean(dependsOnBean);
                    }
                }
                
                //创建单例bean
                if (mbd.isSingleton()) {
                    //这里是一个匿名内部类,创建bean的实例对象,并注册给所依赖的bean
                    sharedInstance = this.getSingleton(beanName, new ObjectFactory<Object>() {
                        public Object getObject() throws BeansException {
                            try {
                                //创建一个指定bean的实例对象,如果有父级继承,则合并子类和父类的定义
                                return AbstractBeanFactory.this.createBean(beanName, mbd, args);
                            } catch (BeansException var2) {
                             
                                //异常,显示的容器单例bean缓存中,清除实例对象
                                AbstractBeanFactory.this.destroySingleton(beanName);
                                throw var2;
                            }
                        }
                    });
                    //获取给定的bean的实例对象
                    bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                } else if (mbd.isPrototype()) {//创建原型模式的实例对象
                    var11 = null;
                    //原型模式,每次都会创建一个新的对象
                    Object prototypeInstance;
                    try {
                        //回调beforePrototypeCreation方法,默认是当前创建的原型对象
                        this.beforePrototypeCreation(beanName);
                        //创建指定bean 实例对象
                        prototypeInstance = this.createBean(beanName, mbd, args);
                    } finally {
                        //回调afterPrototypeCreation
                        this.afterPrototypeCreation(beanName);
                    }
                    //获取指定bean 实例对象
                    bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                } else {//要创建的bean不是单例也不是原型,则根据bean定义资源中配置的生命周期范围,如:request、session

                    String scopeName = mbd.getScope();
                    Scope scope = (Scope)this.scopes.get(scopeName);
                    //如果没有定义生命周期范围,则bean不合法
                    if (scope == null) {
                        throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                    }

                    try {
                    //这里还是一个内部类,获取指定生命周期范围的实例
                        Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
                            public Object getObject() throws BeansException {
                                AbstractBeanFactory.this.beforePrototypeCreation(beanName);

                                Object var1;
                                try {
                                    var1 = AbstractBeanFactory.this.createBean(beanName, mbd, args);
                                } finally {
                                    AbstractBeanFactory.this.afterPrototypeCreation(beanName);
                                }

                                return var1;
                            }
                        });
                         //获取指定bean 实例对象
                        bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                    } catch (IllegalStateException var21) {
                        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", var21);
                    }
                }
            } catch (BeansException var23) {
                this.cleanupAfterBeanCreationFailure(beanName);
                throw var23;
            }
        }

        //对创建的bean实例进行类型检查
        if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
            try {
                return this.getTypeConverter().convertIfNecessary(bean, requiredType);
            } catch (TypeMismatchException var22) {
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Failed to convert bean '" + name + "' to required type [" + ClassUtils.getQualifiedName(requiredType) + "]", var22);
                }

                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        } else {
            return bean;
        }
    }

通过上面IOC容器获取bean方法分析,可以看到在如果bean定义是单例模式,则容器在创建之前先从缓存中查找,以确保容器中只存在一个实例对象。如果是原型模式,则容器每次都会创建一下新的实例对象,除此之外还可以扩展为指定的生命周期范围。

具体的bean的实例创建过程由ObjectFactory接口匿名内部类的createBean()方法完成,ObjectFactory使用了委派模式,具体 的bean的实例创建过程由其实现类AbstractAutowireCapableBeanFactory完成。

2、实例化

其创建bean的实例对象源码如下:


    protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Creating instance of bean '" + beanName + "'");
        }

        RootBeanDefinition mbdToUse = mbd;
        //判断创建的bean是否可以实例化,是否可以通过当前的类加载器加载
        Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }

       //校验和准备bean中的方法覆盖
        try {
            mbdToUse.prepareMethodOverrides();
        } catch (BeanDefinitionValidationException var7) {
            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var7);
        }

        Object beanInstance;
        try {
            //如果bean配置了初始化前和初始化后的处理器,则试图返回一个需要创建bean的代理对象
            beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
            if (beanInstance != null) {
                return beanInstance;
            }
        } catch (Throwable var8) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var8);
        }

        beanInstance = this.doCreateBean(beanName, mbdToUse, args);
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Finished creating instance of bean '" + beanName + "'");
        }

        return beanInstance;
    }


//真正创建bean的方法
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, Object[] args) {
    //封装被创建的bean的对象
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
        }

        if (instanceWrapper == null) {
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }

        final Object bean = instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null;

        //获取实例化对象的类型
        Class<?> beanType = instanceWrapper != null ? instanceWrapper.getWrappedClass() : null;
        //调用PostProcessor 后置处理器
        synchronized(mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                mbd.postProcessed = true;
            }
        }
        
         //向容器中缓存单例模式的bean的对象,以防循环引用
        boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && 
this.isSingletonCurrentlyInCreation(beanName);
        if (earlySingletonExposure) {
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
            }

            //匿名内部类,防止循环引用,今早持有对象的引用
            this.addSingletonFactory(beanName, new ObjectFactory<Object>() {
                public Object getObject() throws BeansException {
                    return AbstractAutowireCapableBeanFactory.this.getEarlyBeanReference(beanName, mbd, bean);
                }
            });
        }

        //bean的对象初始化,依赖注入在此触发
        //这个exposedObject 在初始化完成之后返回作为依赖注入完成后的bean
        Object exposedObject = bean;
        try {
        //将bean实例对象封装起来,并且bean定义中的配置属性赋值给实例对象
            this.populateBean(beanName, mbd, instanceWrapper);
            if (exposedObject != null) {
            //初始化对象
                exposedObject = this.initializeBean(beanName, exposedObject, mbd);
            }
        } catch (Throwable var17) {
            if (var17 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var17).getBeanName())) {
                throw (BeanCreationException)var17;
            }

            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var17);
        }
        
        if (earlySingletonExposure) {
        //获取指定名称已经注册的单例模式的bean对象
            Object earlySingletonReference = this.getSingleton(beanName, false);
            if (earlySingletonReference != null) {
            //获取已经注册的bean和正在实例化的bean是同一个
                if (exposedObject == bean) {
                //当前实例化的bean 初始化完成
                    exposedObject = earlySingletonReference;
                //当前bean依赖其他的bean,并且发送循环引用时,不容许新创建实例对象
                } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
                    String[] dependentBeans = this.getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
                    String[] var12 = dependentBeans;
                    int var13 = dependentBeans.length;

                    //获取当前bean所依赖的其他bean
                    for(int var14 = 0; var14 < var13; ++var14) {
                        String dependentBean = var12[var14];
                        //对依赖的bean进行类型检查
                        if (!this.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.");
                    }
                }
            }
        }

        try {
        //注册---完成依赖注入的bean
            this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
            return exposedObject;
        } catch (BeanDefinitionValidationException var16) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
        }
    }

具体的依赖注入实现其实就是两个方法:

  1. createBeanInstance()方法,生产bean所包含的java对象实例;
  2. populateBean()方法,对bean属性的依赖注入处理。

3、选择bean实例化策略,执行实例化

在createBeanInstance()方法中,根据指定的初始化策略,使用简单工厂、工厂方法或者容器的自动装配特性生成java实例对象。源码如下:

    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
    // 使用工厂对bean实例化
        Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
        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());
        } else if (mbd.getFactoryMethodName() != null) {
          //调用工厂方法创建实例
            return this.instantiateUsingFactoryMethod(beanName, mbd, args);
        } else {
            //使用容器的自动装配的方法进行实例化
            boolean resolved = false;
            boolean autowireNecessary = false;
            if (args == null) {
                synchronized(mbd.constructorArgumentLock) {
                    if (mbd.resolvedConstructorOrFactoryMethod != null) {
                        resolved = true;
                        autowireNecessary = mbd.constructorArgumentsResolved;
                    }
                }
            }

            if (resolved) {
            //调用自动装配的特性,调用匹配的构造方法实例化
                return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
            } else {
             //使用bean的构造方法创建
                Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
                return ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args) ? this.instantiateBean(beanName, mbd) : this.autowireConstructor(beanName, mbd, ctors, args);
            }
        }
    }

对于使用工厂方法和自动装特性的bean的实例化相等清楚,调用构造方法即可完成实例化,但是对最常用的无参构造方法就是使用相应的初始化策略(JDK反射机制)来进行初始化,在方法this.instantiateBean(beanName, mbd)中就具体实现类使用策略实例化。

4、准备依赖注入

上面说过

  1. createBeanInstance()方法,生产bean所包含的java对象实例;
  2. populateBean()方法,对bean属性的依赖注入处理。

AbstractAutowireCapableBeanFactory中的populateBean()方法源码如下:

    protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
        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);
            }
        }
    }

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

          //创建一个定义属性值的解析器,将Bean定义中的属性值解析为bean实例对象的实际值
            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();
                        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);
                }
            }
        }
    }

对属性依赖注入分以下两种情况:

1、属性值类型不需要强制转换时,不需要解析属性值,直接准备进行依赖注入。
2、属性值类型需要强制转换时,首先需要解析属性值,然后对解析后的属性值进行依赖注入。

5、注入赋值

实际注入赋值是AbstractNestablePropertyAccessor 来实现的

BeanWrapperImpl extends AbstractNestablePropertyAccessor implements BeanWrapper
  protected void setPropertyValue(AbstractNestablePropertyAccessor.PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {
        String propertyName = tokens.canonicalName;
        String actualName = tokens.actualName;
        Object propValue;
        if (tokens.keys != null) {
            AbstractNestablePropertyAccessor.PropertyTokenHolder getterTokens = new AbstractNestablePropertyAccessor.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);

            try {
                propValue = this.getPropertyValue(getterTokens);
            } catch (NotReadablePropertyException var20) {
                throw new NotWritablePropertyException(this.getRootClass(), this.nestedPath + propertyName, "Cannot access indexed value in property referenced in indexed property path '" + propertyName + "'", var20);
            }

            String key = tokens.keys[tokens.keys.length - 1];
            if (propValue == null) {
                if (!this.isAutoGrowNestedPaths()) {
                    throw new NullValueInNestedPathException(this.getRootClass(), this.nestedPath + propertyName, "Cannot access indexed value in property referenced in indexed property path '" + propertyName + "': returned null");
                }

                int lastKeyIndex = tokens.canonicalName.lastIndexOf(91);
                getterTokens.canonicalName = tokens.canonicalName.substring(0, lastKeyIndex);
                propValue = this.setDefaultValue(getterTokens);
            }

            Class requiredType;
            Object convertedValue;
            Object newArray;
            AbstractNestablePropertyAccessor.PropertyHandler ph;
            if (propValue.getClass().isArray()) {
                ph = this.getLocalPropertyHandler(actualName);
                requiredType = propValue.getClass().getComponentType();
                int arrayIndex = Integer.parseInt(key);
                Object oldValue = null;

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

                    convertedValue = this.convertIfNecessary(propertyName, 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(actualName, newArray);
                        propValue = this.getPropertyValue(actualName);
                    }

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

                    convertedValue = this.convertIfNecessary(propertyName, 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 var18) {
                                throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + propertyName, "Cannot set element with index " + index + " in List of size " + size + ", accessed using property path '" + propertyName + "': List does not support filling up gaps with null elements");
                            }
                        }

                        list.add(convertedValue);
                    } else {
                        try {
                            list.set(index, convertedValue);
                        } catch (IndexOutOfBoundsException var17) {
                            throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + propertyName, "Invalid list index in property path '" + propertyName + "'", var17);
                        }
                    }
                } else {
                    if (!(propValue 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 Map; returned value was [" + propValue + "]");
                    }

                    ph = this.getLocalPropertyHandler(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, key, requiredType, typeDescriptor);
                    Object oldValue = null;
                    if (this.isExtractOldValueForEditor()) {
                        oldValue = map.get(convertedValue);
                    }

                    newArray = this.convertIfNecessary(propertyName, oldValue, pv.getValue(), mapValueType, ph.nested(tokens.keys.length));
                    map.put(convertedValue, newArray);
                }
            }
        } else {
            AbstractNestablePropertyAccessor.PropertyHandler ph = this.getLocalPropertyHandler(actualName);
            if (ph == null || !ph.isWritable()) {
                if (pv.isOptional()) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Ignoring optional value for property '" + actualName + "' - property not found on bean class [" + this.getRootClass().getName() + "]");
                    }

                    return;
                } else {
                    throw this.createNotWritablePropertyException(propertyName);
                }
            }

            propValue = null;

            PropertyChangeEvent propertyChangeEvent;
            try {
                Object originalValue = pv.getValue();
                Object valueToApply = originalValue;
                if (!Boolean.FALSE.equals(pv.conversionNecessary)) {
                    if (pv.isConverted()) {
                        valueToApply = pv.getConvertedValue();
                    } else {
                        if (this.isExtractOldValueForEditor() && ph.isReadable()) {
                            try {
                                propValue = ph.getValue();
                            } catch (Exception var21) {
                                Exception ex = var21;
                                if (var21 instanceof PrivilegedActionException) {
                                    ex = ((PrivilegedActionException)var21).getException();
                                }

                                if (logger.isDebugEnabled()) {
                                    logger.debug("Could not read previous value of property '" + this.nestedPath + propertyName + "'", ex);
                                }
                            }
                        }

                        valueToApply = this.convertForProperty(propertyName, propValue, originalValue, ph.toTypeDescriptor());
                    }

                    pv.getOriginalPropertyValue().conversionNecessary = valueToApply != originalValue;
                }

                ph.setValue(this.wrappedObject, valueToApply);
            } catch (TypeMismatchException var22) {
                throw var22;
            } catch (InvocationTargetException var23) {
                propertyChangeEvent = new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, propValue, pv.getValue());
                if (var23.getTargetException() instanceof ClassCastException) {
                    throw new TypeMismatchException(propertyChangeEvent, ph.getPropertyType(), var23.getTargetException());
                }

                Throwable cause = var23.getTargetException();
                if (cause instanceof UndeclaredThrowableException) {
                    cause = cause.getCause();
                }

                throw new MethodInvocationException(propertyChangeEvent, cause);
            } catch (Exception var24) {
                propertyChangeEvent = new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, propValue, pv.getValue());
                throw new MethodInvocationException(propertyChangeEvent, var24);
            }
        }

    }

属性依赖注入到bean的实例对象中过程:

1、对于集合类型的属性,将其属性值解析为目标类型的集合后直接赋值给属性
2、对于非集合类型的属性,大量的使用了JDK反射机制,通过属性的getter()方法获取指定属性注入以前的值,同时调用属性的setter()方法为属性设置注入后的值。

这个就是Spring 的setter() 注入原理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值