2.4 IoC容器的依赖注入

上面对IoC容器的初始化过程进行了详细的分析,这个初始化过程完成的主要工作是在IoC容器中建立BeanDefinition数据映射。在此过程中并没有看到IoC容器对Bean依赖关系进行注入,接下来分析一下IoC容器是怎样对Bean的依赖关系进行注入的。

假设当前IoC容器已经载入了用户定义的Bean信息,开始分析依赖注入的原理。首先,注意到依赖注入的过程是用户第一次向IoC容器索要Bean时触发的,当然也有例外,也就是我们可以在BeanDefinition信息中通过控制lazy-init属性来让容器完成对Bean的预实例化。这个预实例化实际上也是一个完成依赖注入的过程,但它是在初始化的过程中完成的,稍后我们会详细分析这个预实例化的处理。当用户向IoC容器索要Bean时,如果读者还有印象,那么一定还记得在基本的IoC容器接口BeanFactory中,有一个getBean的接口定义,这个接口的实现就是触发依赖注入发生的地方。为了进一步了解这个依赖注入过程的实现,下面从DefaultListableBeanFactory的基类AbstractBeanFactory入手去看看getBean的实现,如代码清单2-22所示。

代码清单2-22 getBean触发的依赖注入

        //--------------------------------------------------------------------
        // 这里是对 BeanFactory接口的实现,比如getBean接口方法
        // 这些getBean接口方法最终是通过调用doGetBean来实现的
        //--------------------------------------------------------------------
        public Object getBean(String name) throws BeansException {
            return doGetBean(name, null, null, false);
        }
        public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
            return doGetBean(name, requiredType, null, false);
        }
        public Object getBean(String name, Object... args) throws BeansException {
            return doGetBean(name, null, args, false);
        }
        public <T> T getBean(String name, Class<T> requiredType, Object[] args)
        throws BeansException {
            return doGetBean(name, requiredType, args, false);
        }
        //这里是实际取得Bean的地方,也是触发依赖注入发生的地方
        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 + "'");
                    }
                }
            /*这里的getObjectForBeanInstance完成的是FactoryBean的相关处理,以取得
            FactoryBean的生产结果,  BeanFactoryFactoryBean的区别已经在前面讲过,这个过程在后
            面还会详细地分析*/
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
            }
            else {
                if (isPrototypeCurrentlyInCreation(beanName)) {
                    throw new BeanCurrentlyInCreationException(beanName);
                }
            /*这里对IoC容器中的BeanDefintion是否存在进行检查,检查是否能在当前的BeanFactory中取
              得需要的Bean。如果在当前的工厂中取不到,则到双亲BeanFactory中去取;如果当前的双亲工
              厂取不到,那就顺着双亲BeanFactory链一直向上查找*/
                BeanFactory parentBeanFactory = getParentBeanFactory();
                if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                    String nameToLookup = originalBeanName(name);
                    if (args != null) {
                        return (T) parentBeanFactory.getBean(nameToLookup, args);
                    }
                    else {
                        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);
                    }
                }
                /*这里通过调用createBean方法创建Singleton  bean的实例,这里有一个回调函数
                  getObject,会在getSingleton中调用ObjectFactorycreateBean*/
                //下面会进入到createBean中进行详细分析
                if (mbd.isSingleton()) {
                    sharedInstance = getSingleton(beanName, new ObjectFactory() {
                        public Object getObject() throws BeansException {
                              try {
                                  return createBean(beanName, mbd, args);
                              }
                              catch (BeansException ex) {
                                  destroySingleton(beanName);
                                  throw ex;
                              }
                    }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
                //这里是创建prototype bean的地方
                else if (mbd.isPrototype()) {
                    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;
        }

这个就是依赖注入的入口,在这里触发了依赖注入,而依赖注入的发生是在容器中的BeanDefinition数据已经建立好的前提下进行的。“程序=数据+算法,”很经典的一句话,前面的BeanDefinition就是数据,下面看看这些数据是怎样为依赖注入服务的。虽然依赖注入的过程不涉及复杂的算法问题,但这个过程也不简单,因为我们都知道,对于IoC容器的使用,Spring提供了许多的参数配置,每一个参数配置实际上代表了一个IoC容器的实现特性,这些特性的实现很多都需要在依赖注入的过程中或者对Bean进行生命周期管理的过程中完成。尽管可以用最简单的方式来描述IoC容器,将它视为一个hashMap,但只能说这个hashMap是容器的最基本的数据结构,而不是IoC容器的全部。Spring IoC容器作为一个产品,其价值体现在一系列相关的产品特性上,这些产品特性以依赖反转模式的实现为核心,为用户更好地使用依赖反转提供便利,从而实现了一个完整的IoC容器产品。这些产品特性的实现并不是一个简单的过程,它提供了一个成熟的IoC容器产品供用户使用。所以,尽管Spring IoC容器没有什么独特的算法,但却可以看成是一个成功的软件工程产品,有许多值得我们学习的地方。

关于这个依赖注入的详细过程会在下面进行分析,在图2-14中可以看到依赖注入的一个大致过程。

图2-14 依赖注入的过程

重点来说,getBean是依赖注入的起点,之后会调用createBean,下面通过createBean代码来了解这个实现过程。在这个过程中,Bean对象会依据BeanDefinition定义的要求生成。在AbstractAutowireCapableBeanFactory中实现了这个createBean,createBean不但生成了需要的Bean,还对Bean初始化进行了处理,比如实现了在BeanDefinition中的init-method属性定义,Bean后置处理器等。具体的过程如代码清单2-23所示。

代码清单2-23 AbstractAutowireCapableBeanFactory中的createBean

        protected Object createBean(final String beanName, final RootBeanDefinition
        mbd, final Object[] args)
            throws BeanCreationException {
        AccessControlContext acc = AccessController.getContext();
        return AccessController.doPrivileged(new PrivilegedAction<Object>() {
            public Object run() {
                if (logger.isDebugEnabled()) {
                    logger.debug("Creating instance of bean '" + beanName + "'");
                }
                // 这里判断需要创建的Bean是否可以实例化,这个类是否可以通过类装载器来载入
                resolveBeanClass(mbd, beanName);
                    try {
                    mbd.prepareMethodOverrides();
                }
                catch (BeanDefinitionValidationException ex) {
                    throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
                            beanName, "Validation of method overrides failed", ex);
                }
                try {
                    // 如果Bean配置了PostProcessor,那么这里返回的是一个proxy
                    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;
            }
        }, acc);
        }
        //接着到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的地方,由createBeanInstance来完成
                if (instanceWrapper == null) {
                    instanceWrapper = createBeanInstance(beanName, mbd, args);
                }
                final Object bean = (instanceWrapper != null ?
                instanceWrapper.getWrappedInstance() : null);
                Class beanType = (instanceWrapper != null ? instanceWrapper.
                getWrappedClass() : null);
            synchronized (mbd.postProcessingLock) {
                if (!mbd.postProcessed) {
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                    mbd.postProcessed = true;
                }
            }
            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);
                exposedObject = initializeBean(beanName, exposedObject, mbd);
            }
            catch (Throwable ex) {
                iflt@span b=1> (exlt@span b=1> instanceoflt@span b=1> BeanCreationExceptionlt@span b=1> &&lt@span b=1> 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.");
                            }
                    }
                }
            }
            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来指定的。如代码清单2-24所示,可以看到不同生成方式对应的实现。

代码清单2-24 Bean包含的Java对象的生成

        protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition
        mbd, Object[] args) {
        // 确认需要创建的Bean实例的类可以实例化
        Class beanClass = resolveBeanClass(mbd, beanName);
        //这里使用工厂方法对Bean进行实例化
        if (mbd.getFactoryMethodName() != null)   {
            return instantiateUsingFactoryMethod(beanName, mbd, args);
        }
        if (mbd.resolvedConstructorOrFactoryMethod != null) {
            if (mbd.constructorArgumentsResolved) {
                return autowireConstructor(beanName, mbd, null, args);
            }
            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(String beanName, RootBeanDefinition mbd) {
        //使用默认的实例化策略对Bean进行实例化,默认的实例化策略是
        //CglibSubclassingInstantiationStrategy,也就是使用CGLIB来对Bean进行实例化
            //接着再看CglibSubclassingInstantiationStrategy的实现
            try {
                Object beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
                BeanWrapper bw = new BeanWrapperImpl(beanInstance);
                initBeanWrapper(bw);
                return bw;
            }
            catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                "Instantiation of bean failed", ex);
            }
        }

这里用CGLIB对Bean进行实例化。CGLIB是一个常用的字节码生成器的类库,它提供了一系列的API来提供生成和转换Java的字节码的功能。在Spring AOP中也使用CGLIB对Java的字节码进行增强。在IoC容器中,要了解怎样使用CGLIB来生成Bean对象,需要看一下SimpleInstantiationStrategy类。这个Strategy是Spring用来生成Bean对象的默认类,它提供了两种实例化Java对象的方法,一种是通过BeanUtils,它使用了JVM的反射功能,一种是通过前面提到的CGLIB来生成,如代码清单2-25所示。

代码清单2-25 使用SimpleInstantiationStrategy生成Java对象

        public class SimpleInstantiationStrategy implements InstantiationStrategy {
        public Object instantiate(
                RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
            if (beanDefinition.getMethodOverrides().isEmpty()) {
            //这里取得指定的构造器或者生成对象的工厂方法来对Bean进行实例化
                Constructor constructorToUse = (Constructor) beanDefinition.
                resolvedConstructorOrFactoryMethod;
                if (constructorToUse == null) {
                    Class clazz = beanDefinition.getBeanClass();
                    if (clazz.isInterface()) {
                        throw new BeanInstantiationException(clazz, "Specified class
                        is an interface");
                    }
                    try {
                        constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
                        beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;
                    }
                    catch (Exception ex) {
                        throw new BeanInstantiationException(clazz, "No default
                        constructor found", ex);
                    }
                }
            //通过BeanUtils进行实例化,这个BeanUtils的实例化通过Constructor来实例化Bean,
            //BeanUtils中可以看到具体的调用ctor.newInstance(args)
                return BeanUtils.instantiateClass(constructorToUse, null);
            }
            else {
                //使用CGLIB来实例化对象
                return instantiateWithMethodInjection(beanDefinition, beanName, owner);
            }
        }

在cglibSubclassingInstantiationStrategy中可以看到具体的实例化过程和CGLIB的使用方法,这里就不对CGLIB的使用进行过多阐述了。如果读者有兴趣,可以去阅读CGLIB的使用文档,不过这里的Spring代码可以为使用CGLIB提供很好的参考。这里的Enhancer类,已经是CGLIB的类了,通过这个Enhancer生成Java对象,使用的是Enhancer的create方法,如代码清单2-26所示。

代码清单2-26 使用CGLIB的Enhancer生成Java对象

        public Object instantiate(Constructor ctor, Object[] args) {
        //生成Enhancer对象,并为Enhancer对象设置生成Java对象的参数,比如基类、回调方法等
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(this.beanDefinition.getBeanClass());
            enhancer.setCallbackFilter(new CallbackFilterImpl());
            enhancer.setCallbacks(new Callback[] {
                      NoOp.INSTANCE,
                      new LookupOverrideMethodInterceptor(),
                      new ReplaceOverrideMethodInterceptor()
              });
              //使用CGLIBcreate生成实例化的Bean对象
              return (ctor == null) ?
                      enhancer.create() :
                      enhancer.create(ctor.getParameterTypes(), args);
        }

到这里已经分析了实例化Bean对象的整个过程。在实例化Bean对象生成的基础上,再介绍一下Spring是怎样对这些对象进行处理的,也就是Bean对象生成以后,怎样把这些Bean对象的依赖关系设置好,完成整个依赖注入过程。这个过程涉及对各种Bean对象的属性的处理过程(即依赖关系处理的过程),这些依赖关系处理的依据就是已经解析得到的BeanDefinition。要详细了解这个过程,需要回到前面的populateBean方法,这个方法在AbstractAutowireCapableBeanFactory中的实现如代码清单2-27所示。

代码清单2-27 populateBean的实现

        protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) {
        //这里取得在BeanDefinition中设置的property值,这些property来自对BeanDefinition的解析
        //具体的解析过程可以参看对载入和解析BeanDefinition的分析
              PropertyValues pvs = mbd.getPropertyValues();
              if (bw == null) {
                  if (!pvs.isEmpty()) {
                        throw new BeanCreationException(
                              mbd.getResourceDescription(), beanName, "Cannot apply
                              property values to null instance");
                  }
                  else {
                        return;
                  }
              }
              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);
                  // 这里是对autowire注入的处理,可以根据Bean的名字或者类型,
                  //来完成Beanautowire
                  if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
                      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 = (InstantiationAwareBean
                                PostProcessor) 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);
        }
        //通过applyPropertyValues了解具体的对属性行进行解析然后注入的过程
        protected void applyPropertyValues(String beanName, BeanDefinition mbd,
        BeanWrapper bw, PropertyValues pvs) {
              if (pvs == null || pvs.isEmpty()) {
                  return;
              }
              MutablePropertyValues mpvs = null;
              List<PropertyValue> original;
              if (pvs instanceof MutablePropertyValues) {
                  mpvs = (MutablePropertyValues) pvs;
                  if (mpvs.isConverted()) {
                      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;
            }
            //注意这个BeanDefinitionValueResolverBeanDefinition的解析是在
            //这个valueResolver中完成的
            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);
                      }
                      if (resolvedValue == originalValue) {
                          if (convertible) {
                              pv.setConvertedValue(convertedValue);
                          }
                          deepCopy.add(pv);
                      }
                      else if (originalValue instanceof TypedStringValue && convertible &&
                              !(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进行解析,然后注入到property中。下面到BeanDefinitionValueResolver中去看一下解析过程的实现,以对Bean reference进行解析为例,如图2-15所示,可以看到整个Resolve的过程。具体的对Bean reference进行解析的过程如代码清单2-28所示。

图2-15 Resolve的调用过程

代码清单2-28 对Bean Reference的解析

        private Object resolveReference(Object argName, RuntimeBeanReference ref) {
            try {
            //RuntimeBeanReference取得reference的名字,这个RuntimeBeanReference是在
            //载入BeanDefinition时根据配置生成的
                  String refName = ref.getBeanName();
                  refName = String.valueOf(evaluate(refName));
                  //如果ref是在双亲IoC容器中,那就到双亲IoC容器中去获取
                  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);
                  }
        //在当前IoC容器中去获取Bean,这里会触发一个getBean的过程,如果依赖注入没有发生,这里会
        //触发相应的依赖注入的发生
                  elselt@span b=1> {
                      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);
              }
        }
        //下面看一下对其他类型的属性进行注入的例子,比如arraylist
        private Object resolveManagedArray(Object argName, List<?> ml, Class elementType) {
              Object resolved = Array.newInstance(elementType, ml.size());
              for (int i = 0; i < ml.size(); i++) {
                  Array.set(resolved, i,
                  resolveValueIfNecessary(
                                argName + " with key " + BeanWrapper.PROPERTY_KEY_PREFIX + i +
                                BeanWrapper.PROPERTY_KEY_SUFFIX,
                                ml.get(i)));
              }
              return resolved;
        }
        //对于每一个在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(
                                argName + " with key " + BeanWrapper.PROPERTY_KEY_PREFIX + i +
                                BeanWrapper.PROPERTY_KEY_SUFFIX,
                                ml.get(i)));
              }
              return resolved;
        }

这两种属性的注入都调用了resolveValueIfNecessary,这个方法包含了所有对注入类型的处理。下面看一下resolveValueIfNecessary的实现,如代码清单2-29所示。

代码清单2-29 resolveValueIfNecessary的实现

        public Object resolveValueIfNecessary(Object argName, Object value) {
            //这里对RuntimeBeanReference进行解析,RuntimeBeanReference是在
            //BeanDefinition进行解析时生成的数据对象
            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) {
                  BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
                  return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.
                  getBeanDefinition());
              }
              else if (value instanceof BeanDefinition) {
                  BeanDefinition bd = (BeanDefinition) value;
                  return resolveInnerBean(argName, "(inner bean)", bd);
              }
          //这里对ManageArray进行解析
              else if (value instanceof ManagedArray) {
                  ManagedArray array = (ManagedArray) value;
                  Class elementType = array.resolvedElementType;
                  if (elementType == null) {
                        String elementTypeName = array.getElementTypeName();
                        if (StringUtils.hasText(elementTypeName)) {
                            try {
                                elementType = ClassUtils.forName(elementTypeName, this.
                                beanFactory.getBeanClassLoader());
                                array.resolvedElementType = elementType;
                            }
                            catch (Throwable ex) {
                                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);
              }
          //这里对ManageList进行解析
              else if (value instanceof ManagedList) {
                  return resolveManagedList(argName, (List<?>) value);
              }
          //这里对ManageSet进行解析
              else if (value instanceof ManagedSet) {
                  return resolveManagedSet(argName, (Set<?>) value);
              }
          //这里对ManageMap进行解析
              else if (value instanceof ManagedMap) {
                  return resolveManagedMap(argName, (Map<?, ?>) value);
              }
          //这里对ManageProperties进行解析
              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 = ((TypedStringValue) propKey).getValue();
                        }
                        if (propValue instanceof TypedStringValue) {
                            propValue = ((TypedStringValue) propValue).getValue();
                        }
                        copy.put(propKey, propValue);
                    }
                    return copy;
              }
          //这里对TypedStringValue进行解析
              else if (value instanceof TypedStringValue) {
                    TypedStringValue typedStringValue = (TypedStringValue) value;
                    Object valueObject = evaluate(typedStringValue.getValue());
                    try {
                        Class resolvedTargetType = resolveTargetType(typedStringValue);
                        if (resolvedTargetType != null) {
                            return this.typeConverter.convertIfNecessary
                            (valueObject, resolvedTargetType);
                        }
                        else {
                            return valueObject;
                        }
                    }
                    catch (Throwable ex) {
                            throw new BeanCreationException(
                            this.beanDefinition.getResourceDescription(), this.beanName,
                            "Error converting typed String value for " + argName, ex);
                    }
              }
              else {
                    return evaluate(value);
              }
          }
          //RuntimeBeanReference类型的注入在resolveReference
              private Object resolveReference(Object argName, RuntimeBeanReference ref) {
                    try {
              //RuntimeBeanReference取得reference的名字,这个RuntimeBeanReference是在
              //载入BeanDefinition时根据配置生成的
                    String refName = ref.getBeanName();
                    refName = String.valueOf(evaluate(refName));
              //如果ref是在双亲IoC容器中,那就到双亲IoC容器中去获取
                    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);
                    }
          //在当前IoC容器中取得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);
              }
          }
          //manageList的处理过程在resolveManagedList
          private List resolveManagedList(Object argName, List<?> ml) {
              List<Object> resolved = new ArrayList<Object>(ml.size());
              for (int i = 0; i < ml.size(); i++) {
                    //通过递归的方式,对List的元素进行解析
                    resolved.add(
                      resolveValueIfNecessary(
                                    argName + " with key " + BeanWrapper.PROPERTY_
                                    KEY_PREFIX + i + BeanWrapper.PROPERTY_KEY_SUFFIX,
                                    ml.get(i)));
              }
              return resolved;
          }

在完成这个解析过程后,已经为依赖注入准备好了条件,这是真正把Bean对象设置到它所依赖的另一个Bean的属性中去的地方,其中处理的属性是各种各样的。依赖注入的发生是在BeanWrapper的setPropertyValues中实现的,具体的完成却是在BeanWrapper的子类BeanWrapperImpl中实现的,如代码清单2-30所示。

代码清单2-30 BeanWraper完成Bean的属性值注入

        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;
                  //getPropertyValue取得Bean中对注入对象的引用,比如Array、List、Map、Set
                  try {
                      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);
                  }
                  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()) {
                      Class requiredType = propValue.getClass().getComponentType();
                      int arrayIndex = Integer.parseInt(key);
                      Object oldValue = null;
                      try {
                          if (isExtractOldValueForEditor()) {
                                    oldValue = Array.get(propValue, arrayIndex);
                          }
                          Object convertedValue = this.typeConverterDelegate.
                          convertIfNecessary(
                              propertyName, oldValue, pv.getValue(), requiredType);
                          Array.set(propValue, Integer.parseInt(key), convertedValue);
                      }
                  catch (IllegalArgumentException ex) {
                      PropertyChangeEvent pce =
                              new PropertyChangeEvent(this.rootObject, this.nestedPath +
                              propertyName,oldValue, pv.getValue());
                      throw new TypeMismatchException(pce, requiredType, ex);
                  }
                  catch (IllegalStateException ex) {
                      PropertyChangeEvent pce =
                              new PropertyChangeEvent(this.rootObject, this.nestedPath +
                              propertyName, oldValue, pv.getValue());
                      throw new ConversionNotSupportedException(pce, requiredType, ex);
                  }
                  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);
                  }
                  try {
                      Object convertedValue = this.typeConverterDelegate.
                      convertIfNecessary(
                                    propertyName, oldValue, pv.getValue(), requiredType);
                      iflt@span b=1> (indexlt@span b=1> <lt@span b=1> list.size())lt@span b=1> {
                          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);
                      }
                  }
                  catch (IllegalArgumentException ex) {
                      PropertyChangeEvent pce =
                              new PropertyChangeEvent(this.rootObject, this.nestedPath
                              + propertyName, oldValue, pv.getValue());
                      throw new TypeMismatchException(pce, requiredType, ex);
                      }
                  } //这里对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;
                      Object convertedMapKey;
                      Object convertedMapValue;
                      try {
                          convertedMapKey = this.typeConverterDelegate.
                          convertIfNecessary(key, mapKeyType);
                      }
                  catch (IllegalArgumentException ex) {
                      PropertyChangeEvent pce =
                              new PropertyChangeEvent(this.rootObject, this.nestedPath +
                              propertyName, null, pv.getValue());
                      throw new TypeMismatchException(pce, mapKeyType, ex);
                  }
                  Object oldValue = null;
                  if (isExtractOldValueForEditor()) {
                      oldValue = map.get(convertedMapKey);
                      }
                  trylt@span b=1> {
                      convertedMapValue = this.typeConverterDelegate.convertIfNecessary(
                              propertyName, oldValue, pv.getValue(), mapValueType, null,
                              new MethodParameter(pd.getReadMethod(), -1, tokens.keys.length + 1));
                  }
                  catch (IllegalArgumentException ex) {
                      PropertyChangeEvent pce =
                              new PropertyChangeEvent(this.rootObject, this.nestedPath +
                              propertyName, oldValue, pv.getValue());
                      throw new TypeMismatchException(pce, mapValueType, ex);
                      }
                      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) {
                              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) {
                                  Method readMethod = pd.getReadMethod();
                                    if (!Modifier.isPublic(readMethod.
                                    getDeclaringClass().getModifiers())) {
                                    readMethod.setAccessible(true);
                              }
                              try {
                                    oldValue = readMethod.invoke(this.object);
                              }
                              catch (Exception ex) {
                                  iflt@span b=1> (logger.isDebugEnabled())lt@span b=1> {
                                      logger.debug("Could not read previous value of property '" +
                                              this.nestedPath + propertyName + "'", ex);
                                    }
                                }
                              }
                              valueToApply = this.typeConverterDelegate.convertIfNecessary
                              (oldValue, originalValue, pd);
                              }
                              pv.getOriginalPropertyValue().conversionNecessary = (valueToApply !=
                              originalValue);
                      }
                      //这里取得注入属性的set方法,通过反射机制,把对象注入进去
                      Method writeMethod = pd.getWriteMethod();
                      if (!Modifier.isPublic(writeMethod.getDeclaringClass().
                              getModifiers())) {
                              writeMethod.setAccessible(true);
                      }
                      writeMethod.invoke(this.object, valueToApply);
                  }
                  catch (InvocationTargetException ex) {
                      PropertyChangeEvent propertyChangeEvent =
                              new PropertyChangeEvent(this.rootObject, this.nestedPath +
                              propertyName, oldValue, pv.getValue());
                      if (ex.getTargetException() instanceof ClassCastException) {
                              throw new TypeMismatchException(propertyChange
                              Event, pd.getPropertyType(),ex.getTargetException());
                      }
                      else {
                              throw new MethodInvocationException(propertyChangeEvent, ex.
                              getTargetException());
                      }
                  }
                  catch (IllegalArgumentException ex) {
                      PropertyChangeEvent pce =
                              new PropertyChangeEvent(this.rootObject, this.nestedPath +
                              propertyName, oldValue, pv.getValue());
                      throw new TypeMismatchException(pce, pd.getPropertyType(), ex);
                  }
                  catch (IllegalStateException ex) {
                      PropertyChangeEvent pce =
                              new PropertyChangeEvent(this.rootObject, this.nestedPath +
                              propertyName, oldValue, pv.getValue());
                      throw new ConversionNotSupportedException(pce, pd.getPropertyType(), ex);
                  }
                  catch (IllegalAccessException ex) {
                      PropertyChangeEvent pce =
                              new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName,
                              oldValue, pv.getValue());
                      throw new MethodInvocationException(pce, ex);
                  }
            }
        }

这样就完成了对各种Bean属性的依赖注入过程。从代码实现细节上看,对比Spring 2.0的源代码实现,Spring 3.0的源代码已经有了很大的改进,整个过程更为清晰了,特别是关于依赖注入的部分。如果读者有兴趣,可以比较一下Spring 2.0和Spring 3.0关于依赖注入部分的代码实现,这样可以更清晰地看到Spring源代码的演进过程,也可以看到Spring团队对代码进行重构的思路。

在Bean的创建和对象依赖注入的过程中,需要依据BeanDefinition中的信息来递归地完成依赖注入。从上面的几个递归过程中可以看到,这些递归都是以getBean为入口的。一个递归是在上下文体系中查找需要的Bean和创建Bean的递归调用;另一个递归是在依赖注入时,通过递归调用容器的getBean方法,得到当前Bean的依赖Bean,同时也触发对依赖Bean的创建和注入。在对Bean的属性进行依赖注入时,解析的过程也是一个递归的过程。这样,根据依赖关系,一层一层地完成Bean的创建和注入,直到最后完成当前Bean的创建。有了这个顶层Bean的创建和对它的属性依赖注入的完成,意味着和当前Bean相关的整个依赖链的注入也完成了。

在Bean创建和依赖注入完成以后,在IoC容器中建立起一系列依靠依赖关系联系起来的Bean,这个Bean已经不是简单的Java对象了。该Bean系列以及Bean之间的依赖关系建立完成以后,通过IoC容器的相关接口方法,就可以非常方便地供上层应用使用了。继续以水桶为例,到这里,我们不但找到了水源,而且成功地把水装到了水桶中,同时对水桶里的水完成了一系列的处理,比如消毒、煮沸⋯⋯尽管还是水,但经过一系列的处理以后,这些水已经是开水了,可以直接饮用了。