本文基于Spring4.2.7版本,由于Bean的处理是Spring的核心模块,所以版本之间也没有太大的差异

从源码中看端倪

相信大家多少有些基本的概念了,我们就从源码中来看看Spring是如何加载Bean的。

java
 // 从IOC容器中获取bean的基本方法
 // 了解Spring的同学应该知道,getXXX往往是预处理,doGetXXX才是真正的获取
  @SuppressWarnings("unchecked")
  protected <T> T doGetBean(
      final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
      throws BeansException {

// 如果是bean的别名或者bean的工厂名都会在这里处理掉
// bean的工厂名(bean名称前加&符号)也是Spring用于防止循环依赖和松耦合的创新方法
    final String beanName = transformedBeanName(name);
    Object bean;

    // 首先在单例集合中取,大多数情况下,交给IOC管理的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,返回它自己或工厂Bean创建的实例
      bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    else {
      if (isPrototypeCurrentlyInCreation(beanName)) {//如果正在被创建,就抛出异常
        throw new BeanCurrentlyInCreationException(beanName);
      }

      BeanFactory parentBeanFactory = getParentBeanFactory();//取本容器的父容器
      if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {//若存在父容器,且本容器不存在对应的Bean定义
        String nameToLookup = originalBeanName(name);//取原始的Bean名
        if (args != null) {//若参数列表存在
          // 那么用父容器根据原始Bean名和参数列表返回
          return (T) parentBeanFactory.getBean(nameToLookup, args);
        }
        else {
          // 参数列表不要求,那就直接根据原始名称和要求的类型返回
          return parentBeanFactory.getBean(nameToLookup, requiredType);
        }
      }

      //如果不需要类型检查,标记其已经被创建
      if (!typeCheckOnly) {
        markBeanAsCreated(beanName);
      }

      //根据beanName取其根Bean定义
      final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
      checkMergedBeanDefinition(mbd, beanName, args);

      String[] dependsOn = mbd.getDependsOn();//得到这个根定义的所有依赖
      if (dependsOn != null) {
        for (String dependsOnBean : dependsOn) {
          getBean(dependsOnBean);//注册这个Bean
          //注册一个Bean和依赖于它的Bean(后参数依赖前参数)
          registerDependentBean(dependsOnBean, beanName);
        }
      }

      // 如果Bean定义是单例,就在返回单例
      if (mbd.isSingleton()) {
        sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
          public Object getObject() throws BeansException {
            try {
              return createBean(beanName, mbd, args);
            }
            catch (BeansException ex) {
              destroySingleton(beanName);
              throw ex;
            }
          }
        });
        //根据给定的实例是否为工厂Bean,返回它自己或工厂Bean创建的实例
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
      }
      //如果是原型
      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>() {
            public Object getObject() throws BeansException {
              beforePrototypeCreation(beanName);
              try {
                return createBean(beanName, mbd, args);//原型创建前,与当前线程绑定
              }
              finally {
                原型创建后,与当前线程解除绑定
                afterPrototypeCreation(beanName);
              }
            }
          });
          //根据给定的实例是否为工厂Bean,返回它自己或工厂Bean创建的实例
          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);
        }
      }
    }