Spring-IoC容器的依赖注入原理分析
标签:Spring

IoC容器的依赖注入原理分析

依赖注入的过程时用户第一次向IoC容器索要Bean的时候触发的,当然我们也可以设置 lazy-init属性来让容器完成对Bean的预实例化。即BeanFactory中的getBean的接口实现就是触发依赖注入的地方

现在看 AbstractFactory中的getBean的方法,是去调用 doGetBean

@Override
public Object getBean(String name) throws BeansException {
    return doGetBean(name, null, null, false);
}

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

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

      // Eagerly check singleton cache for manually registered singletons.
//    先从缓存中取得Bean,处理那些已经被创建过的Singleton的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 + "'");
            }
         }
         bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
      } else {
         // Fail if we're already creating this bean instance:
         // We're assumably within a circular reference.
// 		这里假设循环依赖存在,将会抛出异常          
         if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
         }
         
//       对当前的BeanDefinition的工厂进行检查,看能否取到Bean,否则一路向上寻找双亲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 (parentBeanFactory instanceof AbstractBeanFactory) {
               return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                     nameToLookup, requiredType, args, typeCheckOnly);
            } else 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的名字取得BeanDefinition
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);
            
//          取得当前Bean的所有依赖Bean,触发getBean的递归调用,直到取到一个没有任何依赖的Bean为止
            // Guarantee initialization of beans that the current bean depends on.
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
               for (String dep : dependsOn) {
                  if (isDependent(beanName, dep)) {
                     throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                           "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                  }
                  registerDependentBean(dep, beanName);
                  try {
                     getBean(dep);
                  } catch (NoSuchBeanDefinitionException ex) {
                     throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                           "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                  }
               }
            }

            // Create bean instance.
//          创建SingletonBean
            if (mbd.isSingleton()) {
               sharedInstance = getSingleton(beanName, () -> {
                  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);
            } else if (mbd.isPrototype()) {
//             创建PrototypeBean
               // 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 name '" + scopeName + "'");
               }
               try {
                  Object scopedInstance = scope.get(beanName, () -> {
                     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进行类型检查
      // Check if required type matches the type of the actual bean instance.
      if (requiredType != null && !requiredType.isInstance(bean)) {
         try {
            T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
            if (convertedBean == null) {
               throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
            return convertedBean;
         } 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;
   }

上面的循环依赖将会抛出下面这样异常

	public BeanCurrentlyInCreationException(String beanName) {
		super(beanName,
				"Requested bean is currently in creation: Is there an unresolvable circular reference?");
	}

doGetBean中又会去调用createBean,creatBean方法会生成Bean并进行初始化处理,在 AbstractAutowireCapableBeanFactory 完成createBean

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

      // Instantiate the bean.
      BeanWrapper instanceWrapper = null;
      if (mbd.isSingleton()) {
//       如果是单例的,先把缓存中的同名bean清除
         instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
      }
//    这里是创建Bean的地方
      if (instanceWrapper == null) {
         instanceWrapper = createBeanInstance(beanName, mbd, args);
      }
      final Object bean = instanceWrapper.getWrappedInstance();
      Class<?> beanType = instanceWrapper.getWrappedClass();
      if (beanType != NullBean.class) {
         mbd.resolvedTargetType = beanType;
      }

      // Allow post-processors to modify the merged bean definition.
      synchronized (mbd.postProcessingLock) {
         if (!mbd.postProcessed) {
            try {
               applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            } catch (Throwable ex) {
               throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                     "Post-processing of merged bean definition failed", ex);
            }
            mbd.postProcessed = true;
         }
      }

      // Eagerly cache singletons to be able to resolve circular references
      // even when triggered by lifecycle interfaces like BeanFactoryAware.
      boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
            isSingletonCurrentlyInCreation(beanName));
      if (earlySingletonExposure) {
         if (logger.isDebugEnabled()) {
            logger.debug("Eagerly caching bean '" + beanName +
                  "' to allow for resolving potential circular references");
         }
         addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
      }

//    对Bean进行初始化,依赖注入往往从这里发生
      // Initialize the bean instance.
      Object exposedObject = bean;
      try {
         populateBean(beanName, mbd, instanceWrapper);
         exposedObject = initializeBean(beanName, exposedObject, mbd);
      } catch (Throwable ex) {
         if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
            throw (BeanCreationException) ex;
         } else {
            throw new BeanCreationException(
                  mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
         }
      }

      if (earlySingletonExposure) {
         Object earlySingletonReference = getSingleton(beanName, false);
         if (earlySingletonReference != null) {
            if (exposedObject == bean) {
               exposedObject = earlySingletonReference;
            } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
               String[] dependentBeans = getDependentBeans(beanName);
               Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
               for (String dependentBean : dependentBeans) {
                  if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                     actualDependentBeans.add(dependentBean);
                  }
               }
               if (!actualDependentBeans.isEmpty()) {
                  throw new BeanCurrentlyInCreationException(beanName,
                        "Bean with name '" + beanName + "' has been injected into other beans [" +
                              StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                              "] in its raw version as part of a circular reference, but has eventually been " +
                              "wrapped. This means that said other beans do not use the final version of the " +
                              "bean. This is often the result of over-eager type matching - consider using " +
                              "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
               }
            }
         }
      }

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

      return exposedObject;
   }

后面还会对Bean进行实例化,再使用 populateBean对Bean进行属性注入,后面再分析一下:cry:

  • 5 min read

CONTRIBUTORS


  • 5 min read