非单例Bean的获取

Spring Bean获取的主体代码在AbstractBeanFactory的doGetBean方法中,看下面的方法:

protected <T> T doGetBean(
          final String name, final Class&lt;T&gt; requiredType, final Object[] args, boolean typeCheckOnly)
          throws BeansException {
     // 转换BeanName,如果name参数传过来是aliasName的话,在这里会根据aliasName取出真正的BeanName
     final String beanName = transformedBeanName(name);
     Object 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 + "'");
               }
          }
         // 将取出的object(可能是一个FactoryBean)转换成Bean的类型
         bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
     }

     else {
          // 检查是否已经在创建中,如果正在创建中,就确定存在循环引用
          if (isPrototypeCurrentlyInCreation(beanName)) {
               throw new BeanCurrentlyInCreationException(beanName);
          }

          // 检查ParentBeanFactory是否存在Bean定义信息
          BeanFactory parentBeanFactory = getParentBeanFactory();
          if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
               // 如果ParentBeanFacotory不为空而且此BeanFactory不包含Bean定义信息
               String nameToLookup = originalBeanName(name);
               if (args != null) {
                    // 如果参数不为空,带上参数将获取Bean委托给ParentBeanFactory
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
               }
               else {
                    // 如果参数为空,则将获取Bean委托给ParentBeanFactory的标准getBean方法
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
               }
          }

          // typeCheckOnly,实例用来做类型检测的,而不是真正地拿来用的
          if (!typeCheckOnly) {
               markBeanAsCreated(beanName);
          }

          // 如果Bean的定义信息在子Bean定义信息中,则合并到当前的Bean定义信息中
          final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
          checkMergedBeanDefinition(mbd, beanName, args);

          // 处理depends on的情况,确保当前Bean依赖的Bean先创建
          String[] dependsOn = mbd.getDependsOn();
          if (dependsOn != null) {
               for (String dependsOnBean : dependsOn) {
                    getBean(dependsOnBean);
                    registerDependentBean(dependsOnBean, beanName);
               }
          }

          // 开始创建Bean实例
          if (mbd.isSingleton()) {
               sharedInstance = getSingleton(beanName, new ObjectFactory() {
                    public Object getObject() throws BeansException {
                         try {
                              return createBean(beanName, mbd, args);
                         }
                         catch (BeansException ex) {
                              // Explicitly remove instance from singleton cache: It might have been put there
                              // eagerly by the creation process, to allow for circular reference resolution.
                              // Also remove any beans that received a temporary reference to the bean.
                              destroySingleton(beanName);
                              throw ex;
                         }
                    }
               });
               bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
          }

          elseif (mbd.isPrototype()) {
               // Bean的Scope是Prototype,创建一个新实例
               Object prototypeInstance = null;
               try {
                    // 在Bean创建之前,默认行为是:将当前Bean标记为正在创建中,用于前面检测循环引用
                    beforePrototypeCreation(beanName);
                    prototypeInstance = createBean(beanName, mbd, args);
               }
               finally {
                    // 在Bean创建之后,默认行为是:将当前Bean标记为不在创建中,用于前面检测循环引用
                    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实例和需要的类型是否匹配
     if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
          throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
     }
     return (T) bean;
}

从这里可以看出,Spring是首先尝试从单例缓存中获取Bean,如果找不到,然后在根据不同的Bean Scope调用不同的方法去创建Bean。