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

     

     

     

  • 相关阅读:
    使用cordova,监听安卓机物理返回按键,实现退出程序的功能
    使用cordova network-information 插件监听手机网络状态
    使用cordova,使html5也能像IOS,Android那样可以 调取手机的相机拍照功能
    使用canvas给图片添加水印, canvas转换base64,,canvas,图片,base64等转换成二进制文档流的方法,并将合成的图片上传到服务器,
    phpStudy的安装和配置
    小程序入坑(一)---如何引入iconfont 字体图标
    HTML5 原生API input file 来实现多图上传,并大图预览
    webpack引入全局jQuery
    前端滑动分页获取数据(jQuery)
    开源蚂蚁笔记自建服务器
  • 原文地址:https://www.cnblogs.com/mjorcen/p/3582999.html
Copyright © 2011-2022 走看看