zoukankan      html  css  js  c++  java
  • 5.2:缓存中获取单例bean

    5.2  缓存中获取单例bean

    介绍过FactoryBean的用法后,我们就可以了解bean加载的过程了。前面已经提到过,单例在Spring的同一个容器内只会被创建一次,后续再获取bean直接从单例缓存中获取,当然这里也只是尝试加载,首先尝试从缓存中加载,然后再次尝试尝试从singletonFactories中加载。因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,Spring创建bean的原则是不等bean创建完成就会将创建beanObjectFactory提早曝光加入到缓存中,一旦下一个bean创建时需要依赖上

     

     

     1 public Object getSingleton(String beanName) {
     2      //参数true设置标识允许早期依赖    
     3     return getSingleton(beanName, true);
     4 }
     5 
     6 protected Object getSingleton(String beanName, boolean allowEarlyReference) {
     7          //检查缓存中是否存在实例
     8          Object singletonObject = this.singletonObjects.get(beanName);
     9          if (singletonObject == null) {
    10              //如果为空,则锁定全局变量并进行处理
    11              synchronized (this.singletonObjects) {
    12                  //如果此bean正在加载则不处理
    13                  singletonObject = this.earlySingletonObjects.get(beanName);
    14                  if (singletonObject == null && allowEarlyReference) {
    15                      //当某些方法需要提前初始化的时候则会调用addSingletonFactory方法将对应的ObjectFactory初始化策略存储在singletonFactories
    16                      ObjectFactory singletonFactory = this.singletonFactories.get (beanName);
    17                      if (singletonFactory != null) {
    18                          //调用预先设定的getObject方法
    19                          singletonObject = singletonFactory.getObject();
    20                          //记录在缓存中,earlySingletonObjects和singletonFactories互斥
    21                          this.earlySingletonObjects.put(beanName, singletonObject);
    22                          this.singletonFactories.remove(beanName);
    23                      }
    24                  }
    25              }
    26          }
    27          return (singletonObject != NULL_OBJECT ? singletonObject : null);
    28      }

     

      这个方法因为涉及循环依赖的检测,以及涉及很多变量的记录存取,所以让很多读者摸不着头脑。这个方法首先尝试从singletonObjects里面获取实例,如果获取不到再从earlySingleton Objects里面获取,如果还获取不到,再尝试从singletonFactories里面获取beanName对应的ObjectFactory,然后调用这个ObjectFactorygetObject来创建bean,并放到earlySingleton Objects里面去,并且从singletonFacotories里面remove掉这个ObjectFactory,而对于后续的所有内存操作都只为了循环依赖检测时候使用,也就是在allowEarlyReferencetrue的情况下才会使用。

     

     

     

    这里涉及用于存储bean的不同的map,可能让读者感到崩溃,简单解释如下。

     

      singletonObjects用于保存BeanName和创建bean实例之间的关系,bean name --> bean instance

     

      singletonFactories:用于保存BeanName和创建bean的工厂之间的关系,bean name --> ObjectFactory

     

      earlySingletonObjects:也是保存BeanName和创建bean实例之间的关系,与singletonObjects的不同之处在于,当一个单例bean被放到这里面后,那么当bean还在创建过程中,就可以通过getBean方法获取到了,其目的是用来检测循环引用。

     

      registeredSingletons:用来保存当前所有已注册的bean

     

     

     

  • 相关阅读:
    因为数据库无法大写循环所有要使用shell
    mysql动态扩容调研
    MySQL扩容
    数据库死锁及解决死锁问题
    SQL数据库常见故障及解决方法
    通过Ajax方式上传文件(input file),使用FormData进行Ajax请求
    Ajax方式上传文件
    高并发解决方案--负载均衡
    对TCP/IP协议的深入浅出总结
    常用的php开发工具有哪些?
  • 原文地址:https://www.cnblogs.com/mjorcen/p/3582999.html
Copyright © 2011-2022 走看看