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

    假设IoC容器已经载入了用户定义的Bean信息。首先,注入到依赖注入的过程是“用户第一次向IoC容器索要Bean”时,触发索要Bean的相关属性和方法的依赖注入。当然也有例外,也就是我们可以在BeanDefinition信息中通过控制lazy-init属性来让容器完成对Bean的预实例化。这个预实例化实际上也 是一个完成依赖注入的过程,但它是在初始化的过程中完成的,稍后我们分析这个预实例化处理。

    我们先看一下整个流程图,然后再一点点给大家介绍这个依赖注入的过程。

为什么spring依赖注入找不到resource spring依赖注入的作用_依赖注入



    上面说了依赖注入的过程是“用户第一次向IoC容器索要Bean时触发的,那是向谁索要?如何索要的呢?

    当然是谁保有Bean信息,就向谁索要了,也就是向我们最开始最开始讲的BeanFactory进行索要,索要的方法就是BeanFactory定义的getBean()接口。调用这个接口,就等于触发依赖注入了。为了详细说明,我们进入DefaultListableBeanFactory的基类AbstractBeanFactory中去看看getBean的实现。进入到getBean方法中,你会看到它实际调用的是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,处理那些已经被创建过的Singleton的Bean,对这种Bean的请求不需要重复创建
         // Eagerly check singleton cache for manually registered singletons.
         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的相关处理,它会根据我们传入的sharedInstance操作。
            //如果sharedInstance不是FactoryBean的话,就直接返回我们传进来的sharedInstance;
            //如果是的话,就利用我们传进来的FactoryBean(也就是sharedInstance)来生成我们索要的Bean。(下面也有此方法的调用)
            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);
             }
            // 这里检查IoC容器中是否存在beanName所代表的BeanDefinition。如果当前工厂中取不到,则到双亲BeanFactory中去取,            // 如果当前的双亲BeanFactory中取不到,就顺着双亲BeanFactory链一直向上查找。当然如果在双亲BeanFactory中
            // 查找到了的话,注入或生成等操作就在双亲BeanFactory中进行了,就不继续向下进行了
             // Check if bean definition exists in this factory.
             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);
             }

             try {                // 根据Bean的名字(beanName)取得BeanDefinition
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                 checkMergedBeanDefinition(mbd, beanName, args);                // 获取当前Bean的所有依赖Bean,这样会触发getBean的递归调用,直到取到一个没有任务依赖的Bean为止。
                // 这里就相当于,当前getBean方法的依赖注入还有没进行完成,就跳去做取得其它Bean,如果其它Bean还有依赖的话,
                // 就先去取其它Bean的依赖。
                 // Guarantee initialization of beans that the current bean depends on.
                 String[] dependsOn = mbd.getDependsOn();
                 if (dependsOn != null) {
                     for (String dependsOnBean : dependsOn) {                        //如果beanName所依赖的dependsOnBean,已经存在于beanName的依赖列表里,就报错
                        if (isDependent(beanName, dependsOnBean)) {
                             throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                     "Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
                         }
                         registerDependentBean(dependsOnBean, beanName);
                         getBean(dependsOnBean);
                     }
                 }

                 // Create bean instance.
                 if (mbd.isSingleton()) {                    //getSingleton方法是它在的基类DefaultSingletonBeanRegistry中实现的。这个方法的第二个参数是使用一个接口类做为回调。
                    //主要目的是让其它地方去做实现创建SingletonBean。
                    //让其它地方去实现创建SingltonBean的话,为什么要使用参数为接口的方式,而不是继承一个接口,在方法里面调用这个接口,
                    //然后让子类去实现呢?想了一下,可能不全面。用现在这种方式的话:1,实现的地方可以解耦,可以是一套独立的类。
                    //但如果要是用后面那种方法的放,必须是这个类的子类来实现,强制把实现创建SingltonBean的事,加到了它的子类上
                    //(虽然代码的实际实现方式,还是在接口类调用了子类中的方法)。
                    sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
                         @Override
                         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);
                 }
                // 这里创建是ProtoTypeBean的地方
                 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<Object>() {
                             @Override
                             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);
                     }
                 }
             }
             catch (BeansException ex) {
                 cleanupAfterBeanCreationFailure(beanName);
                 throw ex;
             }
         }
        // 这里对创建的Bean进行检查,如果没有问题,就返回这个新创建的Bean,这个Bean已经是包含了依赖关系的Bean
         // Check if required type matches the type of the actual bean instance.
         if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
             try {
                 return getTypeConverter().convertIfNecessary(bean, requiredType);
             }
             catch (TypeMismatchException ex) {
                 if (logger.isDebugEnabled()) {
                     logger.debug("Failed to convert bean '" + name + "' to required type [" +
                             ClassUtils.getQualifiedName(requiredType) + "]", ex);
                 }
                 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
             }
         }
         return (T) bean;
     }    上面介绍了取得Bean的大概过程,主要讲的是几件事:
• 如果缓存中能取得我们想要的Bean,取得那些已经被创建过的Singleton的Bean,对这种Bean的请求不需要重复创建
• 如果缓存中不能取得的话,并且有parentBeanFactory的话,就从parentBeanFactory中取
• 如果parentBeanFactory中也取不到的话,那就根据Bean的类型(Singlton或Prototype或其它)去创建我们Bean(createBean方法)。

    创建Bean,是在createBean方法中进行的,要我们要介绍的依赖注入也是在这里进行的。这个方法是在AbstractAutowireCapableBeanFactory类中,下面我们介绍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是否可以实例化,这个类是否可以通过类装载器来载入        // Make sure bean class is actually resolved at this point.
        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 {            // 如果配置了PostProcessor,那么这里返回的是一具proxy。
            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
             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;
     }看完了上面的代码,我们发现在createBean方法里做下面几件事:
• 创建Bean之前,先判断需要创建的Bean是否可以实例化,这个类是否可以通过类装载器来载入
• 如果配置了PostProcessor,那么这里返回的是一具proxy。
• 如果没有配置PostProcessor,就调用子方法创建Bean

这里的主要工作是进行“Bean是否可以实例化,这个类是否可以通过类装载器来载入”,和是否配置“PostProcessor”的检查,如果都没什么问题,再继续创建Bean。继续创建Bean的方法是doCreateBean方法,代码如下:
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
         // Instantiate the bean.
         BeanWrapper instanceWrapper = null;
         if (mbd.isSingleton()) {
             instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
         }
         if (instanceWrapper == null) {            // 生成Bean。这个Bean是放在BeanWrapper里的。通过BeanWrapper,能对Bean做更多的事
            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) {            ......
        }

         // Initialize the bean instance.
         Object exposedObject = bean;
         try {            // 通过BeanDefinition,对上面生成的Bean,设置Bean的属性
            populateBean(beanName, mbd, instanceWrapper);
             if (exposedObject != null) {                // 初始化Bean。调用的初始化方法如下:
                // 1,如果Bean实现了Aware系列的接口的话,调用这些接口的实现。
postProcessBeforeInitialization和postProcessAfterInitialization 回调方法的调用,
                 //      为Bean实例初始化之前和之后做一些处理。
调用Bean实例对象初始化的方法,这个初始化方法是在Spring Bean定义配置文件中通过init-method属性指定的                 exposedObject = initializeBean(beanName, exposedObject, mbd);
             }
         }
         catch (Throwable ex) {           ......
        }

         if (earlySingletonExposure) {
                           ......        }

         // Register bean as disposable.
         try {
             registerDisposableBeanIfNecessary(beanName, bean, mbd);
         }
         catch (BeanDefinitionValidationException ex) {
             throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
         }

         return exposedObject;
     }

上面的方法主要做了以下几件事:

  • 生成Bean
  • 通过BeanDefinition,对上面生成的Bean,设置(注入)Bean的属性
  • 初始化Bean

从上面的总结可以看到,这个方法中的处理属于比较核心的处理。这里和依赖注入关系特别密切的方法是createBeanInstance和populateBean这两个方法,下载介绍这两个方法。


createBeanInstance方法的代码如下:
    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
        // 确认要创建Bean实例的类是否可以实例化
        // Make sure bean class is actually resolved at this point.
         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());
         }

         if (mbd.getFactoryMethodName() != null)  {           // 用工厂方法对Bean进行实例化
            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) {            // 如果构造函数的参数使用了Autowire的话,调用autowireConstructor进行实例化
            if (autowireNecessary) {
                 return autowireConstructor(beanName, mbd, null, null);
             }
             else {
                 return instantiateBean(beanName, mbd);
             }
         }
        // 使用构造函数进行实例化
         // Need to determine the constructor...
         Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
         if (ctors != null ||
                 mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
                 mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
             return autowireConstructor(beanName, mbd, ctors, args);
         }
        // 使用默认构造函数来初始化
         // No special handling: simply use no-arg constructor.
         return instantiateBean(beanName, mbd);
     }以上代码做了几件事:
• 确认要创建Bean实例的类是否可以实例化
• 如果构造函数的参数使用了Autowire的话,调用autowireConstructor进行实例化
• 如果没有使用Autowire的话,用instantiateBean进行实例化。

在createBeanInstance方法中生成了Bean所包含的Java对象,这个对象的生成有很多种不同的方式,可以通过工厂方法生成,也可以通过容器的Autowire特性。这些生成方式都是通过相关的BeanDefinition来指定的。接下来我们看看最常用的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>() {
                     @Override
                     public Object run() {                        // 使用默认的实例化策略对Bean进行实例化,默认的实例化策略是CglibSubclassingInstantiationStrategy方式,也就是用CGLIB来对Bean进行实例化。
                        return getInstantiationStrategy().instantiate(mbd, beanName, parent);
                     }
                 }, getAccessControlContext());
             }
             else {
                 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);
         }
     }
     这里做了一件事:用CGLIB对Bean进行实例化。CGLIB是一个常用的“字节码”生成器的类库。它提供了一系列的API来提供生成和转换Java字节码功能。具体的实例化过程不在这里详细说明了,有兴趣大家可以看一看。    到这里为止实例化Bean的整个过程已经说明完了。接下来要介绍在Bean生成以后,怎样把这些Bean对象的依赖关系设置好,完成整个依赖注入的过程。这个过程涉及对各种Bean对象的属性的处理过程(即依赖关系处理的过程)。这些依赖关系的处理依据就是已经解析得到的BeanDefinition。要了解这个过程,让我们看看上面说的populateBean方法。代码如下:
    protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
         PropertyValues pvs = mbd.getPropertyValues();

         if (bw == null) {
             ......
         }

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

        // 注入前的准备。把带Autowire并且没有被注入的属性给找出来,并调用容器的getBean方法,取得属性相对应的类Bean,        // 然后加入到PropertyValues中。(查找Autowire并且没有被注入的属性的动作是在unsatisfiedNonSimpleProperties方法里做。)
        // 在下面,把这些准备好的Bean设置到属性中,完成注入的整个过程
         if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
                 mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
             MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

             // Add property values based on autowire by name if applicable.
             if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
                 autowireByName(beanName, mbd, bw, newPvs);
             }

             // Add property values based on autowire by type if applicable.
             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, mbd.allowCaching);
             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);
             }
         }
        // 取得上面准备好PropertyValues,把PropertyValues解析成Bean,设置到属性上。
         applyPropertyValues(beanName, mbd, bw, pvs);
     }看完上面方法的代码,明白了上面代码主要做了两件事:
• 把要注入的属性所对应的Bean生成出来,并保存起来。
• 取得上面准备好PropertyValues,把PropertyValues解析成Bean,设置到属性上。

再接再厉,我们分析一下,解析PropertyValues并设置Bean到要被注入的属性上的代码:
    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());
             }
         }
        // 如果PropertyValues的是MutablePropertyValues的类型的实例的话,直接把PropertyValues设置属性上。(设置的过程也是挺复杂的)
        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;
         }
         BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
        // 如果PropertyValues的不是MutablePropertyValues的类型的实例的话,在这里对PropertyValues进行解析。        // 解析之前是先建立一个PropertyValues的副本(就是深拷贝),然后对副本进行解析,然后注入到Bean里。
        // Create a deep copy, resolving any references for values.
         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();
         }

         // Set our (possibly massaged) deep copy.
         try {            // 这里是注入的地方
            bw.setPropertyValues(new MutablePropertyValues(deepCopy));
         }
         catch (BeansException ex) {
             throw new BeanCreationException(
                     mbd.getResourceDescription(), beanName, "Error setting property values", ex);
         }
     }看了上面的代码,明白了设置过程如下:
• 如果PropertyValues的是MutablePropertyValues的类型的实例的话,直接把PropertyValues设置到属性上。
• 如果不是,就建立PropertyValues的副本,然后解析,最后设置到属性上。

接下来,我们再细看一下解析和设置的过程。首先我们看一下解析的过程:
    public Object resolveValueIfNecessary(Object argName, Object value) {
        // 这里对RuntimeBeanReference进行解析。RuntimeBeanReference是在对BeanDefinition进行解析时生成的数据对象。
         // RuntimeBeanReference一个不可变的,用来保存BeanDefinition的属性值的类。主要是用在BeanFactory中,做指向其它Bean的引用,
        // 要被用来注入的Bean就保存在它当中。
        //  在注入的时候,可以设置根据名字注入还是类型注入,RuntimeBeanReference就是使用在根据类型注入时;
        // 而根据名字注入时,使用RuntimeBeanNameReference,这个类的使用就在RuntimeBeanReference的下面
        // 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(doEvaluate(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;
             String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
                     ObjectUtils.getIdentityHexString(bd);
             return resolveInnerBean(argName, innerBeanName, bd);
         }        // 下面是对ManagedArray,ManagedList,ManagedSet,ManagedMap,ManagedProperties和TypedStringValue的解析。
        // TypedStringValue类型,保存一个String类型的属性value和Object类型的targetType属性。可以根据targetType的类型,来解析value值,把value转换成相对的类。
        else if (value instanceof ManagedArray) {
            .......
            return resolveManagedArray(argName, (List<?>) value, elementType);
         }
         else if (value instanceof ManagedList) {
             // May need to resolve contained runtime references.
             return resolveManagedList(argName, (List<?>) value);
         }
         else if (value instanceof ManagedSet) {
             // May need to resolve contained runtime references.
             return resolveManagedSet(argName, (Set<?>) value);
         }
         else if (value instanceof ManagedMap) {
             // May need to resolve contained runtime references.
             return resolveManagedMap(argName, (Map<?, ?>) value);
         }
         else if (value instanceof ManagedProperties) {
             Properties original = (Properties) value;
             Properties copy = new Properties();
             for (Map.Entry<Object, Object> 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);
         }
     }上面的代码主要做了一件事:
• 根据value的类型,进行不同类型的解析(例如:RuntimeBeanReference,RuntimeBeanNameReference,BeanDefinitionHolder,BeanDefinition,ManagedArray等)

在上面的解析中,又调用了resolveReference方法,我们继续看一看resolveReference方法的代码:
    private Object resolveReference(Object argName, RuntimeBeanReference ref) {
         try {            // 从RuntimeBeanReference中取得reference的名字,这个RuntimeBeanReference是在BeanDefinition载入时,根据配置生成的
             refName = String.valueOf(doEvaluate(refName));
             String refName = ref.getBeanName();
             refName = String.valueOf(doEvaluate(refName));            // 如果ref是在Parent IoC容器中,就到Parent 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);
             }
             else {                // 否则就到当前IoC容器中取得Bean。这里会触发一个getBean的过程,会形成递归调用。
                //  如果通过getBean所取得的Bean有依赖的话,就会重复从最开始到现在,并且还有下面没有讲完的这个整个过程。
                // 等getBean所取得的Bean的整个过程结束后,继续当前Bean的注入(设置)过程。
                //(因为当前方法就是解析的过程,所以当前方法结束后,就开始进行注入的过程了)
                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);
         }
     }这个方法完成了几件事:
• 如果ref是在Parent IoC容器中,就到Parent IoC容器中去获取。
• 否则就到当前IoC容器中取得Bean。(取得Bean时可能会发生递归的getBean调用)
到此,解析的过程说完了。
    最后,我们再来看一下设置的过程。完成解析过程后,已经为依赖注入准备好了条件,这是真正把Bean对象设置到它所依赖的另一个Bean的属性中去的地方,其中处理的属性是各种各样的。依赖注入的发生是在BeanWapper的setPropertyValues中实现的,具体的完成却是在BeanWrapper的子类BeanWrapperImpl中实现的。
调用过程如下:
AbstractAutowireCapableBeanFactory#applyPropertyValues -> bw.setPropertyValues(new MutablePropertyValues(deepCopy))
    AbstractPropertyAccessor#setPropertyValues -> setPropertyValue(pv) (这个setPropertyValue(pv)方法被它的子类BeanWrapperImpl给重写了)
        BeanWrapperImpl#setPropertyValue(PropertyValue pv) -> setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv)
setPropertyValues方法的代码如下:
     private void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) throws BeansException { 

         String propertyName = tokens.canonicalName; 

         String actualName = tokens.actualName; 


        if (tokens.keys != null) {
            // 设置Tokens的索引和keys(到底是干什么用的,还没有分析)
             // Apply indexes and map keys: fetch value for all keys but the last one. 

             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 {
                // 取得要被注入的对象的引用,比例类中某个属性要被注入的话,就取得这个属性的引用。
                 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) { 

                 // null map value case 

                 if (isAutoGrowNestedPaths()) { 

                     // TODO: cleanup, this is pretty hacky 

                     int lastKeyIndex = tokens.canonicalName.lastIndexOf('['); 

                     getterTokens.canonicalName = tokens.canonicalName.substring(0, lastKeyIndex); 

                     propValue = setDefaultValue(getterTokens); 

                 } 

                 else { 

                     throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + propertyName, 

                             "Cannot access indexed value in property referenced " + 

                             "in indexed property path '" + propertyName + "': returned null"); 

                 } 

            }
            // 如果取得要被注入的对象的引用是Array等集合类型的话,利用引用,把要注入的数据加到引用的集合里。
             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() && arrayIndex < Array.getLength(propValue)) { 

                         oldValue = Array.get(propValue, arrayIndex); 

                     } 

                     Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(), 

                             requiredType, TypeDescriptor.nested(property(pd), tokens.keys.length)); 

                     int length = Array.getLength(propValue); 

                     if (arrayIndex >= length && arrayIndex < this.autoGrowCollectionLimit) { 

                         Class<?> componentType = propValue.getClass().getComponentType(); 

                         Object newArray = Array.newInstance(componentType, arrayIndex + 1); 

                         System.arraycopy(propValue, 0, newArray, 0, length); 

                         setPropertyValue(actualName, newArray); 

                         propValue = getPropertyValue(actualName); 

                     } 

                     Array.set(propValue, arrayIndex, convertedValue); 

                 } 

                 catch (IndexOutOfBoundsException ex) { 

                     throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName, 

                             "Invalid array index in property path '" + propertyName + "'", ex); 

                 } 

             } 

             else if (propValue instanceof List) { 

                ...... 

             } 

             else if (propValue instanceof Map) { 

               ......
        }
        // 这里是对非集合类进行注入
         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>() { 

                                         @Override 

                                         public Object run() { 

                                             readMethod.setAccessible(true); 

                                             return null; 

                                         } 

                                     }); 

                                 } 

                                 else { 

                                     readMethod.setAccessible(true); 

                                 } 

                             } 

                             try { 

                                 if (System.getSecurityManager() != null) { 

                                     oldValue = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { 

                                         @Override 

                                         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, new TypeDescriptor(property(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>() { 

                             @Override 

                             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>() { 

                             @Override 

                             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) {
              ......
            }
 

         } 

    }

上面代码完成的工作如下:

  • 取得要被注入的对象的引用,比例类中某个属性要被注入的话,就取得这个属性的引用。
  • 如果取得要被注入的对象的引用是Array等集合类型的话,利用引用,把要注入的数据加到引用的集合里。
  • 如果不是集合类的话,取得要注入的对象的引用的Set方法,通过反射机制,把对象注入进去。

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

    在Bean创建和依赖注入完成以后,在IoC这容器中建立起一系列依靠依赖关系联系起来的Bean,这个Bean已经不是简单的Java对象了。该Bean系列以及Bean之间的依赖关系建立完成以后,通过IoC容器的相关接口方法,就可以非常方便地供上层应用使用了。











// beanName依赖于dependentBeanName
     public void registerDependentBean(String beanName, String dependentBeanName) {
         // A quick check for an existing entry upfront, avoiding synchronization...
         String canonicalName = canonicalName(beanName);
         Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
         if (dependentBeans != null && dependentBeans.contains(dependentBeanName)) {
             return;
         }

         // No entry yet -> fully synchronized manipulation of the dependentBeans Set
         synchronized (this.dependentBeanMap) {
             dependentBeans = this.dependentBeanMap.get(canonicalName);
             if (dependentBeans == null) {
                 dependentBeans = new LinkedHashSet<String>(8);
                 this.dependentBeanMap.put(canonicalName, dependentBeans);
             }
             
             //把dependentBeanName的Bean保存beanName的依赖Bean列表里。
             //dependentBeanMap里保存的是,Bean(KEY)和它依赖的Bean列表(Value)
             dependentBeans.add(dependentBeanName);
         }
         synchronized (this.dependenciesForBeanMap) {
             Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(dependentBeanName);
             if (dependenciesForBean == null) {
                 dependenciesForBean = new LinkedHashSet<String>(8);
                 this.dependenciesForBeanMap.put(dependentBeanName, dependenciesForBean);
             }
             //把beanName的Bean,保存到dependentBeanName的被依赖Bean列表中。
             //dependenciesForBeanMap这时保存的是,被其它类依赖的Bean(Key)和依赖它的类列表(Value)
             dependenciesForBean.add(canonicalName);
         }
     }


问题:

1,什么情况下,使用用工厂方法对Bean进行实例化

   Spring容器被创建后,会检查Bean的配置。但直到Bean被创建时,它的属性才会被设置。如果Bean是单例(singleton-scoped)
   并且是预初始化(pre-instantiate)类型的话,它会在容器被创建时,也一起被创建;如果是其他类型的Bean(例如prototyp),只有在Bean被请求的时候,才会被创建。
   Bean的创建会引起一系列的创建,它的依赖和它的依赖的依赖等等。


2,从RuntimeBeanReference中取得reference的名字,这个RuntimeBeanReference是在BeanDefinition载入时,根据配置生成的。根据哪个配置生成的?

3,否则就到当前IoC容器中取得Bean,这里会触发一个getBean的过程,如果依赖注入没有发生,这里会触发依赖注入。有点乱,现在这个不是正在依赖注入吗?还是这里说的是对新的getBean出来的Bean进行依赖注入呢?

4,            // 如果配置了PostProcessor,那么这里返回的是一个proxy。为什么返回一个proxy,这个proxy已经完成了Bean的注入什么的了吗?

5,        // 这里对RuntimeBeanReference进行解析。RuntimeBeanReference是在对BeanDefinition进行解析时生成的数据对象。为什么要用RuntimeBeanReference解析?