DefaultSingletonBeanRegistry


这是DefaultSingletonBeanRegistry类的体系结构,由一个类一个责任的原则


  • AliasRegistry : 提供别名注册的接口
  • SingletonBeanRegistry :  提供单例bean注册的接口
  • ObjectFactory : 这个接口通常用于封装一个通用的工厂,它只有一个方法getObject() ,它调用getObject()方法返回一个新的实例,一些在每次调用的目标对象(原型).
  • DisposableBean : 接口实现为beans要破坏释放资源。它也只有一个方法destroy(),由一个破坏一个singleton的BeanFactory调用。
  • SimpleAliasRegistry: 它简单地实现了AliasRegistry接口。
  • DefaultSingletonBeanRegistry:它继承SimpleAliasRegistry类和实现了SingletonBeanRegistry接口,因此这个类可以有别名注册的功能和单例bean注册的功能,并且他还支持注册DisposableBean实例;它依赖ObjectFactory接口和DisposableBean接口(关闭注册表时调用到了destroy方法)。

Java代码   收藏代码
  1. /** 
  2.  * 共享bean实例的通用注册表,实现了SingletonBeanRegistry. 允许注册表中注册的单例应该被所有调用者共享,通过bean名称获得。 
  3.  *  
  4.  * 还支持登记的DisposableBean实例,(这可能会或不能正确的注册单例),关闭注册表时destroyed. 
  5.  * 可以注册bean之间的依赖关系,执行适当的关闭顺序。 
  6.  *  
  7.  *  
  8.  * 这个类主要用作基类的BeanFactory实现, 提供基本的管理 
  9.  * singleton bean 实例功能。 
  10.  *  
  11.  */  
  12. public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements  
  13.         SingletonBeanRegistry {  
  14.   
  15. //内部标记为一个空的单例对象: 并发 Maps( 不支持空值 )作为标志值。  
  16.     protected static final Object NULL_OBJECT = new Object();  
  17.   
  18. // 日记用来记录子类  
  19.     protected final Log logger = LogFactory.getLog(getClass());  
  20.   
  21. //是存放singleton对象的缓存  
  22.     private final Map singletonObjects = new ConcurrentHashMap();  
  23.   
  24. // 是存放制造singleton的工厂对象的缓存  
  25.     private final Map singletonFactories = new HashMap();  
  26.   
  27. //是存放singletonFactory 制造出来的 singleton 的缓存早期单例对象缓存  
  28.     private final Map earlySingletonObjects = new HashMap();  
  29. //以上三个缓存是这个类存放单例bean的主要Map  
  30. //就是单例注册表  
  31.     private final Set registeredSingletons = new LinkedHashSet(  
  32.             16);  
  33.   
  34. //目前正在创建中的单例bean的名称的集合  
  35.     private final Set singletonsCurrentlyInCreation = Collections  
  36.             .synchronizedSet(new HashSet());  
  37.   
  38. //存放异常出现的相关的原因的集合  
  39.     private Set suppressedExceptions;  
  40.   
  41. //标志,指示我们目前是否在销毁单例中  
  42.     private boolean singletonsCurrentlyInDestruction = false;  
  43.   
  44. //存放一次性bean的缓存  
  45.     private final Map disposableBeans = new LinkedHashMap();  
  46.   
  47. //外部bean与被包含在外部bean的所有内部bean集合包含关系的缓存  
  48.     private final Map> containedBeanMap = new ConcurrentHashMap>();  
  49.   
  50. //指定bean与依赖指定bean的所有bean的依赖关系的缓存  
  51.     private final Map> dependentBeanMap = new ConcurrentHashMap>();  
  52.   
  53. //指定bean与创建这个bean所需要依赖的所有bean的依赖关系的缓存  
  54.     private final Map> dependenciesForBeanMap = new ConcurrentHashMap>();  
  55.   
  56.     // SingletonBeanRegistry接口的registerSingleton方法的实现  
  57.     public void registerSingleton(String beanName, Object singletonObject)  
  58.             throws IllegalStateException {  
  59.         Assert.notNull(beanName, "'beanName' must not be null");  
  60.         synchronized (this.singletonObjects) {  
  61.             Object oldObject = this.singletonObjects.get(beanName);  
  62. //如果singletonObjects缓存找到有指定名称为beanName的对象,则表示该名称已被占用  
  63.             if (oldObject != null) {  
  64.                 throw new IllegalStateException("Could not register object ["  
  65.                         + singletonObject + "] under bean name '" + beanName  
  66.                         + "': there is already object [" + oldObject  
  67.                         + "] bound");  
  68.             }  
  69. //若该名称没被占用,真正的注册操作在这里实现  
  70.             addSingleton(beanName, singletonObject);  
  71.         }  
  72.     }  
  73.   
  74.       
  75.     protected void addSingleton(String beanName, Object singletonObject) {  
  76.         synchronized (this.singletonObjects) {  
  77.             // 因为singletonObjects类型是ConcurrentHashMap,并发Map不支持空值作为标志值,所以用NULL_OBJECT来代替  
  78.             this.singletonObjects.put(beanName,  
  79.                     (singletonObject != null ? singletonObject : NULL_OBJECT));  
  80.             // beanName已被注册存放在singletonObjects缓存,那么singletonFactories不应该再持有名称为beanName的工厂  
  81.             this.singletonFactories.remove(beanName);  
  82.             // beanName已被注册存放在singletonObjects缓存,那么earlySingletonObjects不应该再持有名称为beanName的bean。  
  83.             this.earlySingletonObjects.remove(beanName);  
  84.             // beanName放进单例注册表中  
  85.             this.registeredSingletons.add(beanName);  
  86.         }  
  87.     }  
  88.   
  89.     /** 
  90.      * 添加 名称为beanName的singletonFactory对象 
  91.      *  
  92.      */  
  93.     protected void addSingletonFactory(String beanName,  
  94.             ObjectFactory singletonFactory) {  
  95.         Assert.notNull(singletonFactory, "Singleton factory must not be null");  
  96.         synchronized (this.singletonObjects) {  
  97.             // 判断singletonObjects内名字为beanName是否被占用,若没有,进行注册操作  
  98.             if (!this.singletonObjects.containsKey(beanName)) {  
  99.                 this.singletonFactories.put(beanName, singletonFactory);  
  100.                 this.earlySingletonObjects.remove(beanName);  
  101.                 this.registeredSingletons.add(beanName);  
  102.             }  
  103.         }  
  104.     }  
  105.   
  106.     // SingletonBeanRegistry接口的getSingleton方法的实现  
  107.     public Object getSingleton(String beanName) {  
  108.         return getSingleton(beanName, true);  
  109.     }  
  110.   
  111.   
  112.     protected Object getSingleton(String beanName, boolean allowEarlyReference) {  
  113.         Object singletonObject = this.singletonObjects.get(beanName);  
  114.         // 如果singletonObjects指定beanName的对象是不存在的  
  115.         if (singletonObject == null) {  
  116.             synchronized (this.singletonObjects) {  
  117.                 singletonObject = this.earlySingletonObjects.get(beanName);  
  118.                 // 如果earlySingletonObjects指定的beanName的对象是不存在的且allowEarlyReference是允许的  
  119.                 if (singletonObject == null && allowEarlyReference) {  
  120.                     ObjectFactory singletonFactory = this.singletonFactories  
  121.                             .get(beanName);  
  122.                     // 如果存在指定beanName的singletonFactory对象  
  123.                     if (singletonFactory != null) {  
  124.                         // singletonFactory创建指定的单例对象  
  125.                         singletonObject = singletonFactory.getObject();  
  126.                         // 这里可以看出earlySingletonObjects缓存应该是存放singletonFactory产生的singleton  
  127.                         this.earlySingletonObjects.put(beanName,  
  128.                                 singletonObject);  
  129.                         // 这里表示指定的beanName已被占用,所以要在singletonFactories移除该名称  
  130.                         this.singletonFactories.remove(beanName);  
  131.                     }  
  132.                 }  
  133.             }  
  134.         }  
  135.         return (singletonObject != NULL_OBJECT ? singletonObject : null);  
  136.     }  
  137.   
  138.   
  139.     public Object getSingleton(String beanName, ObjectFactory singletonFactory) {  
  140.         Assert.notNull(beanName, "'beanName' must not be null");  
  141.         synchronized (this.singletonObjects) {  
  142.             Object singletonObject = this.singletonObjects.get(beanName);  
  143.             // 如果singetonObjects缓存不存在名称为beanName的对象  
  144.             if (singletonObject == null) {  
  145.                 // 如果目前在销毁singellton  
  146.                 if (this.singletonsCurrentlyInDestruction) {  
  147.                     throw new BeanCreationNotAllowedException(  
  148.                             beanName,  
  149.                             "Singleton bean creation not allowed while the singletons of this factory are in destruction "  
  150.                                     + "(Do not request a bean from a BeanFactory in a destroy method implementation!)");  
  151.                 }  
  152.                 if (logger.isDebugEnabled()) {  
  153.                     logger.debug("Creating shared instance of singleton bean '"  
  154.                             + beanName + "'");  
  155.                 }  
  156.                 // 单例对象创建前的回调,默认实现注册正在创建的单例  
  157.                 beforeSingletonCreation(beanName);  
  158.                 // 判断存储异常相关原因的集合是否已存在  
  159.                 boolean recordSuppressedExceptions = (this.suppressedExceptions == null);  
  160.                 // 若没有,刚创建异常集合的实例  
  161.                 if (recordSuppressedExceptions) {  
  162.                     this.suppressedExceptions = new LinkedHashSet();  
  163.                 }  
  164.                 try {  
  165.                     // 由参数给定的singletonFactory创建singleton对象,getObject方法的具体实现由ObjectFactory的子类决定  
  166.                     singletonObject = singletonFactory.getObject();  
  167.                 } catch (BeanCreationException ex) {  
  168.                     // 如果异常被抓取,在这里将出现异常的原因抛出  
  169.                     if (recordSuppressedExceptions) {  
  170.                         for (Exception suppressedException : this.suppressedExceptions) {  
  171.                             ex.addRelatedCause(suppressedException);  
  172.                         }  
  173.                     }  
  174.                     throw ex;  
  175.                 } finally {  
  176.                     // 结束前,将异常集合销毁掉  
  177.                     if (recordSuppressedExceptions) {  
  178.                         this.suppressedExceptions = null;  
  179.                     }  
  180.                     // 单例创建之后的回调,默认的实现标志单例不要在创建了。  
  181.                     afterSingletonCreation(beanName);  
  182.                 }  
  183.                 // 注册创建后的单例  
  184.                 addSingleton(beanName, singletonObject);  
  185.             }  
  186.             return (singletonObject != NULL_OBJECT ? singletonObject : null);  
  187.         }  
  188.     }  
  189.   
  190.     /** 
  191.      * 注册 发生在singeton bean 实例创建之间发生的异常  
  192.      */  
  193.     protected void onSuppressedException(Exception ex) {  
  194.         synchronized (this.singletonObjects) {  
  195.             if (this.suppressedExceptions != null) {  
  196.                 this.suppressedExceptions.add(ex);  
  197.             }  
  198.         }  
  199.     }  
  200.   
  201.     /** 
  202.      * 移除名称为beanName的单例,主要在四个集合中移除, 
  203.      * 如singletonObjects,singletonFactories,earlySingletonObjects 
  204.      * ,registeredSingletons 
  205.      *  
  206.      */  
  207.     protected void removeSingleton(String beanName) {  
  208.         synchronized (this.singletonObjects) {  
  209.             this.singletonObjects.remove(beanName);  
  210.             this.singletonFactories.remove(beanName);  
  211.             this.earlySingletonObjects.remove(beanName);  
  212.             this.registeredSingletons.remove(beanName);  
  213.         }  
  214.     }  
  215.   
  216.     // singletonBeanRegistry接口的containsSingleton方法实现  
  217.     public boolean containsSingleton(String beanName) {  
  218.         return (this.singletonObjects.containsKey(beanName));  
  219.     }  
  220.   
  221.     // singletonBeanRegistry接口的getSingletonNames方法实现  
  222.     public String[] getSingletonNames() {  
  223.         // 对singletonObjects加锁,可能是为了防止registeredSingletons和singletonObjects出现不一致的问题  
  224.         synchronized (this.singletonObjects) {  
  225.             return StringUtils.toStringArray(this.registeredSingletons);  
  226.         }  
  227.     }  
  228.   
  229.     // singletonBeanRegistry接口的getSingletonCount方法实现  
  230.     public int getSingletonCount() {  
  231.         synchronized (this.singletonObjects) {  
  232.             return this.registeredSingletons.size();  
  233.         }  
  234.     }  
  235.   
  236.     /** 
  237.      * 单例对象创建前的回调,默认实现singletonsCurrentlyInCreation集合注册正在创建的单例. 
  238.      *  
  239.      */  
  240.     protected void beforeSingletonCreation(String beanName) {  
  241.         if (!this.singletonsCurrentlyInCreation.add(beanName)) {  
  242.             throw new BeanCurrentlyInCreationException(beanName);  
  243.         }  
  244.     }  
  245.   
  246.     /** 
  247.      * 单例创建之后的回调,默认实现singletonCurrentlyInCreation集合移除正在创建的单例 
  248.      *  
  249.      */  
  250.     protected void afterSingletonCreation(String beanName) {  
  251.         if (!this.singletonsCurrentlyInCreation.remove(beanName)) {  
  252.             throw new IllegalStateException("Singleton '" + beanName  
  253.                     + "' isn't currently in creation");  
  254.         }  
  255.     }  
  256.   
  257.     /** 
  258.      * 返回 存放正在创建单例的集合是否包含指定名称为beanName的单例存在 
  259.      *  
  260.      */  
  261.     public final boolean isSingletonCurrentlyInCreation(String beanName) {  
  262.         return this.singletonsCurrentlyInCreation.contains(beanName);  
  263.     }  
  264.   
  265.     /** 
  266.      * 一次性bean注册,存放在disponsableBeans集合中 
  267.      *  
  268.      */  
  269.     public void registerDisposableBean(String beanName, DisposableBean bean) {  
  270.         synchronized (this.disposableBeans) {  
  271.             this.disposableBeans.put(beanName, bean);  
  272.         }  
  273.     }  
  274.   
  275.     /** 
  276.      * 注册两个bean之间的控制关系,例如内部bean和包含其的外部bean之间 
  277.      *  
  278.      */  
  279.     public void registerContainedBean(String containedBeanName,  
  280.             String containingBeanName) {  
  281.         synchronized (this.containedBeanMap) {  
  282.             // 从containedBeanMap缓存中查找外部bean名为containingBeanName的内部bean集合  
  283.             Set containedBeans = this.containedBeanMap  
  284.                     .get(containingBeanName);  
  285.             // 如果没有,刚新建一个存放内部bean的集合,并且存放在containedBeanMap缓存中  
  286.             if (containedBeans == null) {  
  287.                 containedBeans = new LinkedHashSet(8);  
  288.                 this.containedBeanMap.put(containingBeanName, containedBeans);  
  289.             }  
  290.             // 将名为containedBeanName的内部bean存放到内部bean集合  
  291.             containedBeans.add(containedBeanName);  
  292.         }  
  293.         // 紧接着调用注册内部bean和外部bean的依赖关系的方法  
  294.         registerDependentBean(containedBeanName, containingBeanName);  
  295.     }  
  296.   
  297.     /** 
  298.      * 注册给定bean的一个依赖bean,给定的bean销毁之前被销毁。 
  299.      *  
  300.      */  
  301.     public void registerDependentBean(String beanName, String dependentBeanName) {  
  302.         // 调用SimpleAliasRegistry的canonicalName方法,这方法是将参数beanName当做别名寻找到注册名,并依此递归  
  303.         String canonicalName = canonicalName(beanName);  
  304.         synchronized (this.dependentBeanMap) {  
  305.             // 从dependentBeanMap缓存中找到依赖名为canonicalName这个bean的 依赖bean集合  
  306.             Set dependentBeans = this.dependentBeanMap  
  307.                     .get(canonicalName);  
  308.             // 如果为空,则新建一个依赖bean集合,并且存放到dependentBeanMap缓存中  
  309.             if (dependentBeans == null) {  
  310.                 dependentBeans = new LinkedHashSet(8);  
  311.                 this.dependentBeanMap.put(canonicalName, dependentBeans);  
  312.             }  
  313.             // 依赖bean集合添加参数2指定的dependentBeanName  
  314.             dependentBeans.add(dependentBeanName);  
  315.         }  
  316.         synchronized (this.dependenciesForBeanMap) {  
  317.             // 从dependenciesForBeanMap缓存中找到dependentBeanName要依赖的所有bean集合  
  318.             Set dependenciesForBean = this.dependenciesForBeanMap  
  319.                     .get(dependentBeanName);  
  320.             if (dependenciesForBean == null) {  
  321.                 dependenciesForBean = new LinkedHashSet(8);  
  322.                 this.dependenciesForBeanMap.put(dependentBeanName,  
  323.                         dependenciesForBean);  
  324.             }  
  325.             dependenciesForBean.add(canonicalName);  
  326.         }  
  327.     }  
  328.   
  329.     /** 
  330.      *  确定是否还存在名为beanName的被依赖关系 
  331.      */  
  332.     protected boolean hasDependentBean(String beanName) {  
  333.         return this.dependentBeanMap.containsKey(beanName);  
  334.     }  
  335.   
  336.     /** 
  337.      * 返回依赖于指定的bean的所有bean的名称,如果有的话。 
  338.      *  
  339.      */  
  340.     public String[] getDependentBeans(String beanName) {  
  341.         Set dependentBeans = this.dependentBeanMap.get(beanName);  
  342.         if (dependentBeans == null) {  
  343.             return new String[0];  
  344.         }  
  345.         return StringUtils.toStringArray(dependentBeans);  
  346.     }  
  347.   
  348.     /** 
  349.      * 返回指定的bean依赖于所有的bean的名称,如果有的话。 
  350.      *  
  351.      */  
  352.     public String[] getDependenciesForBean(String beanName) {  
  353.         Set dependenciesForBean = this.dependenciesForBeanMap  
  354.                 .get(beanName);  
  355.         // 如果没有的话返回new String[0]而不是null  
  356.         if (dependenciesForBean == null) {  
  357.             return new String[0];  
  358.         }  
  359.         return dependenciesForBean.toArray(new String[dependenciesForBean  
  360.                 .size()]);  
  361.     }  
  362.   
  363.     // 销毁单例  
  364.     public void destroySingletons() {  
  365.         if (logger.isInfoEnabled()) {  
  366.             logger.info("Destroying singletons in " + this);  
  367.         }  
  368.         // 单例目前销毁标志开始  
  369.         synchronized (this.singletonObjects) {  
  370.             this.singletonsCurrentlyInDestruction = true;  
  371.         }  
  372.   
  373.         // 销毁disponsableBeans缓存中所有单例bean  
  374.         synchronized (this.disposableBeans) {  
  375.             String[] disposableBeanNames = StringUtils  
  376.                     .toStringArray(this.disposableBeans.keySet());  
  377.             for (int i = disposableBeanNames.length - 1; i >= 0; i--) {  
  378.                 destroySingleton(disposableBeanNames[i]);  
  379.             }  
  380.         }  
  381.   
  382.         // containedBeanMap缓存清空,dependentBeanMap缓存清空,dependenciesForBeanMap缓存清空  
  383.         this.containedBeanMap.clear();  
  384.         this.dependentBeanMap.clear();  
  385.         this.dependenciesForBeanMap.clear();  
  386.   
  387.         // singeltonObjects缓存清空,singletonFactories缓存清空,earlySingletonObjects缓存清空,registeredSingletons缓存清空  
  388.         synchronized (this.singletonObjects) {  
  389.             this.singletonObjects.clear();  
  390.             this.singletonFactories.clear();  
  391.             this.earlySingletonObjects.clear();  
  392.             this.registeredSingletons.clear();  
  393.             // 单例目前正在销毁标志为结束  
  394.             this.singletonsCurrentlyInDestruction = false;  
  395.         }  
  396.     }  
  397.   
  398.   
  399.     public void destroySingleton(String beanName) {  
  400.         // Remove a registered singleton of the given name, if any.  
  401.         removeSingleton(beanName);  
  402.   
  403.         // Destroy the corresponding DisposableBean instance.  
  404.         DisposableBean disposableBean;  
  405.         synchronized (this.disposableBeans) {  
  406.             disposableBean = (DisposableBean) this.disposableBeans  
  407.                     .remove(beanName);  
  408.         }  
  409.         destroyBean(beanName, disposableBean);  
  410.     }  
  411.   
  412.   
  413.     protected void destroyBean(String beanName, DisposableBean bean) {  
  414.         // Trigger destruction of dependent beans first...  
  415.         // 这段代码告诉我们先移除要销毁依赖bean  
  416.         Set dependencies = this.dependentBeanMap.remove(beanName);  
  417.         if (dependencies != null) {  
  418.             if (logger.isDebugEnabled()) {  
  419.                 logger.debug("Retrieved dependent beans for bean '" + beanName  
  420.                         + "': " + dependencies);  
  421.             }  
  422.             for (String dependentBeanName : dependencies) {  
  423.                 destroySingleton(dependentBeanName);  
  424.             }  
  425.         }  
  426.   
  427.         // Actually destroy the bean now...  
  428.         // 销毁bean实例  
  429.         if (bean != null) {  
  430.             try {  
  431.                 bean.destroy();  
  432.             } catch (Throwable ex) {  
  433.                 logger.error("Destroy method on bean with name '" + beanName  
  434.                         + "' threw an exception", ex);  
  435.             }  
  436.         }  
  437.   
  438.         // Trigger destruction of contained beans...  
  439.         // 从containedBeanMap缓存中移除要销毁的bean,递归移除它的包含内部bean集合  
  440.         Set containedBeans = this.containedBeanMap.remove(beanName);  
  441.         if (containedBeans != null) {  
  442.             for (String containedBeanName : containedBeans) {  
  443.                 destroySingleton(containedBeanName);  
  444.             }  
  445.         }  
  446.   
  447.         // Remove destroyed bean from other beans' dependencies.  
  448.         // 从其它bean的依赖bean集合中移除要销毁的bean  
  449.         synchronized (this.dependentBeanMap) {  
  450.             for (Iterator>> it = this.dependentBeanMap  
  451.                     .entrySet().iterator(); it.hasNext();) {  
  452.                 Map.Entry> entry = it.next();  
  453.                 Set dependenciesToClean = entry.getValue();  
  454.                 dependenciesToClean.remove(beanName);  
  455.                 if (dependenciesToClean.isEmpty()) {  
  456.                     it.remove();  
  457.                 }  
  458.             }  
  459.         }  
  460.   
  461.         // Remove destroyed bean's prepared dependency information.  
  462.         // 最后 从dependenciesForBeanMap缓存中移除要销毁的bean  
  463.         this.dependenciesForBeanMap.remove(beanName);  
  464.     }  
  465.   
  466.     /** 
  467.      * Expose the singleton mutex to subclasses. 
  468.      * 

     

  469.      * Subclasses should synchronize on the given Object if they perform any 
  470.      * sort of extended singleton creation phase. In particular, subclasses 
  471.      * should not have their own mutexes involved in singleton creation, 
  472.      * to avoid the potential for deadlocks in lazy-init situations. 
  473.      */  
  474.     protected final Object getSingletonMutex() {  
  475.         return this.singletonObjects;  
  476.     }  
  477.   
  478. }  
  479.  

一听名字,就知道这是一个SingletonBean注册的地方,此类也实现了SingletonBeanRegistry接口,继承了 SimpleAliasRegistry。这也可以理解,DefaultSingletonBeanRegistry既有管理SingletonBean 的功能,又提供了别名的功能,那当然可以继承SimpleAliasRegistry了。



DefaultSingletonBeanRegistry是一个通用的存储共享bean实例的地方,通过bean的名字获得bean。同时,它也给提供一次性bean的注册功能。


这个类的主要作用是, 给BeanFactory的实现,提供基本的管理 singleton bean 实例功能


这个类中,使用了三个主要的存储器(map)来分别存储 singletonObject,singletonFactory,earlySingletonObject


当注册一个 singleton object 的时候,会在 singletonObject 的存储器中加入此 object,而在其他的两个存储器中移除。当然,这样的行为是可以在子类中去复写的。


在 getSingleton的时候,spring的默认实现是,先从 singleton object 的存储器中去寻找,如果找不到,再从 early singleton object 存储器中寻找,再找不到,那就在寻找对应的 singleton factory,造出所需的 singleton object,然后返回。



而 contains singleton 就是直接检查 singleton object 存储器了,其他的存储器不做检查。


而 get singleton counts 也是统计 singleton object 的数量。


看完了代码,再仔细想想,为什么这个类要使用三个存储器呢?


我想, singletonObjects 就是直观的存储着 singleton 的,而 singletonFactories 是存储的制造 singleton 的工厂,还有一个 earlySingletonObject, 在看了代码之后,我更觉得这是一个 早期singletonFactory 制造出来的 singleton 的缓存


你可能感兴趣的:(Spring)