Spring源码解析之Bean的加载

来源:互联网 发布:nginx反向代理配置文件 编辑:程序博客网 时间:2024/04/29 05:24

本文基于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);        }      }    }
0 0
原创粉丝点击