spring 5.1.4 debug 笔记 第二记 SingletonBeanRegistry

public interface SingletonBeanRegistry {

   /**
    * Register the given existing object as singleton in the bean registry,
    * under the given bean name.
    * 

The given instance is supposed to be fully initialized; the registry * will not perform any initialization callbacks (in particular, it won't * call InitializingBean's {@code afterPropertiesSet} method). * The given instance will not receive any destruction callbacks * (like DisposableBean's {@code destroy} method) either. *

When running within a full BeanFactory: Register a bean definition * instead of an existing instance if your bean is supposed to receive * initialization and/or destruction callbacks. *

Typically invoked during registry configuration, but can also be used * for runtime registration of singletons. As a consequence, a registry * implementation should synchronize singleton access; it will have to do * this anyway if it supports a BeanFactory's lazy initialization of singletons. * @param beanName the name of the bean * @param singletonObject the existing singleton object * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet * @see org.springframework.beans.factory.DisposableBean#destroy * @see org.springframework.beans.factory.support.BeanDefinitionRegistry#registerBeanDefinition */ void registerSingleton(String beanName, Object singletonObject);//注册单例 /** * Return the (raw) singleton object registered under the given name. *

Only checks already instantiated singletons; does not return an Object * for singleton bean definitions which have not been instantiated yet. *

The main purpose of this method is to access manually registered singletons * (see {@link #registerSingleton}). Can also be used to access a singleton * defined by a bean definition that already been created, in a raw fashion. *

NOTE: This lookup method is not aware of FactoryBean prefixes or aliases. * You need to resolve the canonical bean name first before obtaining the singleton instance. * @param beanName the name of the bean to look for * @return the registered singleton object, or {@code null} if none found * @see ConfigurableListableBeanFactory#getBeanDefinition */ @Nullable Object getSingleton(String beanName);获取bean id 对应的对象 /** * Check if this registry contains a singleton instance with the given name. *

Only checks already instantiated singletons; does not return {@code true} * for singleton bean definitions which have not been instantiated yet. *

The main purpose of this method is to check manually registered singletons * (see {@link #registerSingleton}). Can also be used to check whether a * singleton defined by a bean definition has already been created. *

To check whether a bean factory contains a bean definition with a given name, * use ListableBeanFactory's {@code containsBeanDefinition}. Calling both * {@code containsBeanDefinition} and {@code containsSingleton} answers * whether a specific bean factory contains a local bean instance with the given name. *

Use BeanFactory's {@code containsBean} for general checks whether the * factory knows about a bean with a given name (whether manually registered singleton * instance or created by bean definition), also checking ancestor factories. *

NOTE: This lookup method is not aware of FactoryBean prefixes or aliases. * You need to resolve the canonical bean name first before checking the singleton status. * @param beanName the name of the bean to look for * @return if this bean factory contains a singleton instance with the given name * @see #registerSingleton * @see org.springframework.beans.factory.ListableBeanFactory#containsBeanDefinition * @see org.springframework.beans.factory.BeanFactory#containsBean */ boolean containsSingleton(String beanName); 查看bean id 是否注册为单例 /** * Return the names of singleton beans registered in this registry. *

Only checks already instantiated singletons; does not return names * for singleton bean definitions which have not been instantiated yet. *

The main purpose of this method is to check manually registered singletons * (see {@link #registerSingleton}). Can also be used to check which singletons * defined by a bean definition have already been created. * @return the list of names as a String array (never {@code null}) * @see #registerSingleton * @see org.springframework.beans.factory.support.BeanDefinitionRegistry#getBeanDefinitionNames * @see org.springframework.beans.factory.ListableBeanFactory#getBeanDefinitionNames */ String[] getSingletonNames(); 获取所有单例的名称 /** * Return the number of singleton beans registered in this registry. *

Only checks already instantiated singletons; does not count * singleton bean definitions which have not been instantiated yet. *

The main purpose of this method is to check manually registered singletons * (see {@link #registerSingleton}). Can also be used to count the number of * singletons defined by a bean definition that have already been created. * @return the number of singleton beans * @see #registerSingleton * @see org.springframework.beans.factory.support.BeanDefinitionRegistry#getBeanDefinitionCount * @see org.springframework.beans.factory.ListableBeanFactory#getBeanDefinitionCount */ int getSingletonCount(); 获取单例的总数 /** * Return the singleton mutex used by this registry (for external collaborators). * @return the mutex object (never {@code null}) * @since 4.2 */ Object getSingletonMutex();获取 单例注册引导区所用的同步锁 }

 

我们来看一下实现类   DefaultSingletonBeanRegistry

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {

    //存储bean id --->单例对象的 map
   /** Cache of singleton objects: bean name to bean instance. */
   private final Map singletonObjects = new ConcurrentHashMap<>(256);  
   //存储bean id ----> 对应的工厂 工厂中存储着bean id 对应的未初始化完全的实例
   /** Cache of singleton factories: bean name to ObjectFactory. */
   private final Map> singletonFactories = new HashMap<>(16);
   //存储bean id ---> 尚未初始化完全的实例
   /** Cache of early singleton objects: bean name to bean instance. */
   private final Map earlySingletonObjects = new HashMap<>(16);
   // 存储着所有注册单例的bean id 当然 这里面有初始化完整的 还有一些尚未初始化完全的
   /** Set of registered singletons, containing the bean names in registration order. */
   private final Set registeredSingletons = new LinkedHashSet<>(256);
   // 存储正在初始化的bean id
   /** Names of beans that are currently in creation. */
   private final Set singletonsCurrentlyInCreation =
         Collections.newSetFromMap(new ConcurrentHashMap<>(16));
   // 创建检查中不包含的一些bean id 
   /** Names of beans currently excluded from in creation checks. */
   private final Set inCreationCheckExclusions =
         Collections.newSetFromMap(new ConcurrentHashMap<>(16));

   /** List of suppressed Exceptions, available for associating related causes. */
   @Nullable
   private Set suppressedExceptions;
   //单例正在销毁的标志
   /** Flag that indicates whether we're currently within destroySingletons. */
   private boolean singletonsCurrentlyInDestruction = false;
   //存储着需要销毁的 bean id -> 单例 的map
   /** Disposable bean instances: bean name to disposable instance. */
   private final Map disposableBeans = new LinkedHashMap<>();
   //存储着一个类作为外部类 包含的内部类形成的映射 即 containedBeanMap 外部类 作为key
   /** Map between containing bean names: bean name to Set of bean names that the bean contains. */
   private final Map> containedBeanMap = new ConcurrentHashMap<>(16);
   //存储着  bean id ---> 所有需要bean id作为依赖项的bean id 的 map
   /** Map between dependent bean names: bean name to Set of dependent bean names. */
   private final Map> dependentBeanMap = new ConcurrentHashMap<>(64);
   //存储着 bean id ---> bean id 所需要的 所有依赖项的bean id 的map
   /** Map between depending bean names: bean name to Set of bean names for the bean's dependencies. */
   private final Map> dependenciesForBeanMap = new ConcurrentHashMap<>(64);


   @Override
   public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
      Assert.notNull(beanName, "Bean name must not be null");
      Assert.notNull(singletonObject, "Singleton object must not be null");
      synchronized (this.singletonObjects) {
         Object oldObject = this.singletonObjects.get(beanName);  获取单例
         if (oldObject != null) { //如果已经存在 抛出异常 不能再注册单例为这个bean id 因为已经被原有的约束了
            throw new IllegalStateException("Could not register object [" + singletonObject +
                  "] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
         }
         addSingleton(beanName, singletonObject); //如果没有注册过 注册单例 往下看
      }
   }

   /**
    * Add the given singleton object to the singleton cache of this factory.
    * 

To be called for eager registration of singletons. * @param beanName the name of the bean * @param singletonObject the singleton object */ protected void addSingleton(String beanName, Object singletonObject) { synchronized (this.singletonObjects) { this.singletonObjects.put(beanName, singletonObject); singletonObjects 存储的是最终的映射关系 此时单例已经初始化完毕 this.singletonFactories.remove(beanName);需要移除singletonFactories中的映射 因为此时单例已经初始化完毕 singletonFactories存储的是未初始化完成的实例映射 this.earlySingletonObjects.remove(beanName);同样的需要移除 earlySingletonObjects中的映射 因为也是存储的是未完全初始化完整的实例 this.registeredSingletons.add(beanName); 需要加入 registeredSingletons当中 方便统计当前单例 } } /** * Add the given singleton factory for building the specified singleton * if necessary. *

To be called for eager registration of singletons, e.g. to be able to * resolve circular references. * @param beanName the name of the bean * @param singletonFactory the factory for the singleton object */ protected void addSingletonFactory(String beanName, ObjectFactory singletonFactory) { Assert.notNull(singletonFactory, "Singleton factory must not be null"); synchronized (this.singletonObjects) { if (!this.singletonObjects.containsKey(beanName)) { //当前未注册为单例 this.singletonFactories.put(beanName, singletonFactory); 加入singletonFactories中 此时 bean实例尚未初始化完成 this.earlySingletonObjects.remove(beanName); //移除earlySingletonObjects中的映射 this.registeredSingletons.add(beanName);//记录单例 } } } @Override @Nullable public Object getSingleton(String beanName) { return getSingleton(beanName, true);获取单例 } /** * Return the (raw) singleton object registered under the given name. *

Checks already instantiated singletons and also allows for an early * reference to a currently created singleton (resolving a circular reference). * @param beanName the name of the bean to look for * @param allowEarlyReference whether early references should be created or not * @return the registered singleton object, or {@code null} if none found */ @Nullable protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject = this.singletonObjects.get(beanName);//获取单例 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { //如果单例没有被注册 并且 bean id 对应的实例 正在创建 synchronized (this.singletonObjects) { 加锁 singletonObject = this.earlySingletonObjects.get(beanName);从 earlySingletonObjects 中获取实例 如果找不到映射关系 并且 允许获取提前引用 if (singletonObject == null && allowEarlyReference) { ObjectFactory singletonFactory = this.singletonFactories.get(beanName);获取对应的工厂 if (singletonFactory != null) { singletonObject = singletonFactory.getObject();//获取未初始化完全的实例 this.earlySingletonObjects.put(beanName, singletonObject);//放到第二层缓存 this.singletonFactories.remove(beanName);//移除第三级缓存中的映射关系 } } } } return singletonObject; } /** * Return the (raw) singleton object registered under the given name, * creating and registering a new one if none registered yet. * @param beanName the name of the bean * @param singletonFactory the ObjectFactory to lazily create the singleton * with, if necessary * @return the registered singleton object */ public Object getSingleton(String beanName, ObjectFactory singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); synchronized (this.singletonObjects) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { if (this.singletonsCurrentlyInDestruction) { throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction " + "(Do not request a bean from a BeanFactory in a destroy method implementation!)"); } if (logger.isDebugEnabled()) { logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); } beforeSingletonCreation(beanName);//预备动作 往下看 boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try { singletonObject = singletonFactory.getObject();//获取未初始化完全的实例 newSingleton = true; } catch (IllegalStateException ex) { // Has the singleton object implicitly appeared in the meantime -> // if yes, proceed with it since the exception indicates that state. singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { throw ex; } } catch (BeanCreationException ex) { if (recordSuppressedExceptions) { for (Exception suppressedException : this.suppressedExceptions) { ex.addRelatedCause(suppressedException); } } throw ex; } finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } afterSingletonCreation(beanName);//检查bean id 对应的实例是否创建完成 } if (newSingleton) { addSingleton(beanName, singletonObject);注册单例 } } return singletonObject; } } /** * Register an Exception that happened to get suppressed during the creation of a * singleton bean instance, e.g. a temporary circular reference resolution problem. * @param ex the Exception to register */ protected void onSuppressedException(Exception ex) { synchronized (this.singletonObjects) { if (this.suppressedExceptions != null) { this.suppressedExceptions.add(ex); } } } /** * Remove the bean with the given name from the singleton cache of this factory, * to be able to clean up eager registration of a singleton if creation failed. * @param beanName the name of the bean * @see #getSingletonMutex() */ protected void removeSingleton(String beanName) { synchronized (this.singletonObjects) {移除单例 一二三 级缓存 和统计的 都需要清除 this.singletonObjects.remove(beanName); this.singletonFactories.remove(beanName); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.remove(beanName); } } @Override public boolean containsSingleton(String beanName) { return this.singletonObjects.containsKey(beanName); } @Override public String[] getSingletonNames() { synchronized (this.singletonObjects) { return StringUtils.toStringArray(this.registeredSingletons); } } @Override public int getSingletonCount() { synchronized (this.singletonObjects) { return this.registeredSingletons.size(); } } public void setCurrentlyInCreation(String beanName, boolean inCreation) { Assert.notNull(beanName, "Bean name must not be null"); if (!inCreation) { this.inCreationCheckExclusions.add(beanName);//如果创建完成 或者 没创建 加入 } else { this.inCreationCheckExclusions.remove(beanName);正在创建时 移除记录 } } public boolean isCurrentlyInCreation(String beanName) { Assert.notNull(beanName, "Bean name must not be null"); // 分为 两种情况 第一个条件不成立 !this.inCreationCheckExclusions.contains(beanName) ==false 说明 在排除列表中包含bean id 说明 还没创建 如果成立 第二个条件 如果不成立的话 说明 已经创建完了 结果返回false 但是 如果成立的话 说明正在创建 结果返回true return (!this.inCreationCheckExclusions.contains(beanName) && isActuallyInCreation(beanName)); } protected boolean isActuallyInCreation(String beanName) { return isSingletonCurrentlyInCreation(beanName); } /** * Return whether the specified singleton bean is currently in creation * (within the entire factory). * @param beanName the name of the bean */ public boolean isSingletonCurrentlyInCreation(String beanName) { return this.singletonsCurrentlyInCreation.contains(beanName); } /** * Callback before singleton creation. *

The default implementation register the singleton as currently in creation. * @param beanName the name of the singleton about to be created * @see #isSingletonCurrentlyInCreation */ protected void beforeSingletonCreation(String beanName) { //如果创建完成 或者正在创建 会抛出异常 if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } } /** * Callback after singleton creation. *

The default implementation marks the singleton as not in creation anymore. * @param beanName the name of the singleton that has been created * @see #isSingletonCurrentlyInCreation */ protected void afterSingletonCreation(String beanName) { // 如果!this.inCreationCheckExclusions.contains(beanName) == true 就是说 已经创建 或在创建的路上 !this.singletonsCurrentlyInCreation.remove(beanName) == true 代表创建完成 结果抛出异常 单例 bean id 没有正在创建 if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) { throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation"); } } /** * Add the given bean to the list of disposable beans in this registry. *

Disposable beans usually correspond to registered singletons, * matching the bean name but potentially being a different instance * (for example, a DisposableBean adapter for a singleton that does not * naturally implement Spring's DisposableBean interface). * @param beanName the name of the bean * @param bean the bean instance */ public void registerDisposableBean(String beanName, DisposableBean bean) { synchronized (this.disposableBeans) { this.disposableBeans.put(beanName, bean);//注册销毁流程 } } /** * Register a containment relationship between two beans, * e.g. between an inner bean and its containing outer bean. *

Also registers the containing bean as dependent on the contained bean * in terms of destruction order. * @param containedBeanName the name of the contained (inner) bean * @param containingBeanName the name of the containing (outer) bean * @see #registerDependentBean */ public void registerContainedBean(String containedBeanName, String containingBeanName) { synchronized (this.containedBeanMap) { //检查外部类 containingBeanName 是否有内部类 没有的话 新建 一个set集合 Set containedBeans = this.containedBeanMap.computeIfAbsent(containingBeanName, k -> new LinkedHashSet<>(8)); //如果外部类 有内部类 并且 内部类 containedBeanName 在set集合中 结束程序 if (!containedBeans.add(containedBeanName)) { return; } } registerDependentBean(containedBeanName, containingBeanName); } /** * Register a dependent bean for the given bean, * to be destroyed before the given bean is destroyed. * @param beanName the name of the bean * @param dependentBeanName the name of the dependent bean */ public void registerDependentBean(String beanName, String dependentBeanName) { String canonicalName = canonicalName(beanName);//查找最终的bean id beanName 可能也是一个别名 需要找到一个没有作为别名的bean id 的内部类 //dependentBeanMap 作为一个 key 为内部类 value 为 所有需要它作为依赖的类的集合 synchronized (this.dependentBeanMap) { Set dependentBeans = this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8)); if (!dependentBeans.add(dependentBeanName)) { return; } } //dependenciesForBeanMap 作为一个 key 为 外部类 value 为 所有 该类依赖的类的集合 synchronized (this.dependenciesForBeanMap) { Set dependenciesForBean = this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8)); dependenciesForBean.add(canonicalName); } } /** * Determine whether the specified dependent bean has been registered as * dependent on the given bean or on any of its transitive dependencies. * @param beanName the name of the bean to check * @param dependentBeanName the name of the dependent bean * @since 4.0 */ //判断是否dependentBeanName 依赖于 beanName 或者传递依赖于 beanName protected boolean isDependent(String beanName, String dependentBeanName) { synchronized (this.dependentBeanMap) { return isDependent(beanName, dependentBeanName, null); } } // private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set alreadySeen) { //alreadySeen 这个list 不空表示 dependentBeanName 过滤掉的 那些不依赖于beanName 的集合 如果一开始传进来的就不为空 并且 包括 beanName 就说明 dependentBeanName 不依赖于 beanName if (alreadySeen != null && alreadySeen.contains(beanName)) { 这是个出口 往下看 return false; } String canonicalName = canonicalName(beanName); Set dependentBeans = this.dependentBeanMap.get(canonicalName); //查询出所有的依赖于canonicalName 的类的集合 if (dependentBeans == null) { //不依赖 return false return false; } if (dependentBeans.contains(dependentBeanName)) { //依赖 return true return true; } for (String transitiveDependency : dependentBeans) { if (alreadySeen == null) { alreadySeen = new HashSet<>(); } alreadySeen.add(beanName);//存储那些过滤掉的beanName 对应的实例 if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) { return true; } } return false; } /** * Determine whether a dependent bean has been registered for the given name. * @param beanName the name of the bean to check */ //确定是否为beanName注册了依赖bean protected boolean hasDependentBean(String beanName) { return this.dependentBeanMap.containsKey(beanName); } /** * Return the names of all beans which depend on the specified bean, if any. * @param beanName the name of the bean * @return the array of dependent bean names, or an empty array if none */ //获取依赖于beanName 的类所组成的数组 public String[] getDependentBeans(String beanName) { Set dependentBeans = this.dependentBeanMap.get(beanName); if (dependentBeans == null) { return new String[0]; } synchronized (this.dependentBeanMap) { return StringUtils.toStringArray(dependentBeans); } } /** * Return the names of all beans that the specified bean depends on, if any. * @param beanName the name of the bean * @return the array of names of beans which the bean depends on, * or an empty array if none */ //获取 beanName 的所有依赖组成的数组 public String[] getDependenciesForBean(String beanName) { Set dependenciesForBean = this.dependenciesForBeanMap.get(beanName); if (dependenciesForBean == null) { return new String[0]; } synchronized (this.dependenciesForBeanMap) { return StringUtils.toStringArray(dependenciesForBean); } } //获取所有注册注销流程的beanName 销毁对应的单例 清空缓存 public void destroySingletons() { if (logger.isTraceEnabled()) { logger.trace("Destroying singletons in " + this); } synchronized (this.singletonObjects) { this.singletonsCurrentlyInDestruction = true; } String[] disposableBeanNames; synchronized (this.disposableBeans) { disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet()); } for (int i = disposableBeanNames.length - 1; i >= 0; i--) { destroySingleton(disposableBeanNames[i]); } this.containedBeanMap.clear(); this.dependentBeanMap.clear(); this.dependenciesForBeanMap.clear(); clearSingletonCache(); } /** * Clear all cached singleton instances in this registry. * @since 4.3.15 */ protected void clearSingletonCache() { synchronized (this.singletonObjects) { this.singletonObjects.clear(); this.singletonFactories.clear(); this.earlySingletonObjects.clear(); this.registeredSingletons.clear(); this.singletonsCurrentlyInDestruction = false; //销毁完成 需要重置状态 } } /** * Destroy the given bean. Delegates to {@code destroyBean} * if a corresponding disposable bean instance is found. * @param beanName the name of the bean * @see #destroyBean */ public void destroySingleton(String beanName) { // Remove a registered singleton of the given name, if any. removeSingleton(beanName);//删除缓存中的映射关系 // Destroy the corresponding DisposableBean instance. DisposableBean disposableBean; //移除准备销毁的bean id 和 对应的实例 的映射关系 synchronized (this.disposableBeans) { disposableBean = (DisposableBean) this.disposableBeans.remove(beanName); } destroyBean(beanName, disposableBean);销毁bean } /** * Destroy the given bean. Must destroy beans that depend on the given * bean before the bean itself. Should not throw any exceptions. * @param beanName the name of the bean * @param bean the bean instance to destroy */ protected void destroyBean(String beanName, @Nullable DisposableBean bean) { // Trigger destruction of dependent beans first... Set dependencies; synchronized (this.dependentBeanMap) { // Within full synchronization in order to guarantee a disconnected Set dependencies = this.dependentBeanMap.remove(beanName); //返回依赖 beanName 对应实例的类的set 集合 } if (dependencies != null) { //如果set集合不为空 if (logger.isTraceEnabled()) { logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies); } eg: x 被 y 和 u 依赖 如果 x要销毁的时候 需要 先处理 y 和 u for (String dependentBeanName : dependencies) { destroySingleton(dependentBeanName); } } // Actually destroy the bean now... if (bean != null) { try { bean.destroy(); 销毁 } catch (Throwable ex) { if (logger.isInfoEnabled()) { logger.info("Destroy method on bean with name '" + beanName + "' threw an exception", ex); } } } // Trigger destruction of contained beans... Set containedBeans; synchronized (this.containedBeanMap) { // Within full synchronization in order to guarantee a disconnected Set //外部类作为 key 查找 内部类集合 containedBeans = this.containedBeanMap.remove(beanName); } if (containedBeans != null) { for (String containedBeanName : containedBeans) { destroySingleton(containedBeanName);//销毁内部类 } } //beanName 销毁后 移除 beanName对应实例 对 其他类 依赖的对应映射 // Remove destroyed bean from other beans' dependencies. synchronized (this.dependentBeanMap) { for (Iterator>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) { Map.Entry> entry = it.next(); Set dependenciesToClean = entry.getValue(); dependenciesToClean.remove(beanName); if (dependenciesToClean.isEmpty()) { it.remove(); } } } //移除 beanName 对应实例 --> beanName 所需依赖类的对应关系 // Remove destroyed bean's prepared dependency information. this.dependenciesForBeanMap.remove(beanName); } /** * Exposes the singleton mutex to subclasses and external collaborators. *

Subclasses should synchronize on the given Object if they perform * any sort of extended singleton creation phase. In particular, subclasses * should not have their own mutexes involved in singleton creation, * to avoid the potential for deadlocks in lazy-init situations. */ public final Object getSingletonMutex() { return this.singletonObjects;//获得锁 } }

你可能感兴趣的:(spring源码)