spring单例bean注册表类图
package org.springframework.core; /** * 定义单例别名的注册,查询服务 * @author Juergen Hoeller * @since 2.5.2 */ public interface AliasRegistry { /** * 给指定的bean设置别名 * @param bean名称 * @param alias注册的别名 * @throws IllegalStateException if the alias is already in use * and may not be overridden */ void registerAlias(String name, String alias); /** * 从注册表中移除指定的别名 * @param alias the alias to remove * @throws IllegalStateException if no such alias was found */ void removeAlias(String alias); /** * 判断给点的名称是否是别名 * (as opposed to the name of an actually registered component). * @param name the name to check * @return whether the given name is an alias */ boolean isAlias(String name); /** * 返回指定bean名称的多有别名 * @param name the name to check for aliases * @return the aliases, or an empty array if none */ String[] getAliases(String name); }
package org.springframework.core; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.util.StringValueResolver; /** * 提供单例别名的注册,查询服务 * @author Juergen Hoeller * @since 2.5.2 */ public class SimpleAliasRegistry implements AliasRegistry { /** 别名缓存(线程安全的 )别名为key,name是value */ private final MapaliasMap = new ConcurrentHashMap (16); @Override public void registerAlias(String name, String alias) { //注册别名时:name和别名不能为空 Assert.hasText(name, "'name' must not be empty"); Assert.hasText(alias, "'alias' must not be empty"); //如果name已经注册,就移除 if (alias.equals(name)) { this.aliasMap.remove(alias); } else { //通过别名获取对应的name String registeredName = this.aliasMap.get(alias); if (registeredName != null) { //name也相同,直接返回 if (registeredName.equals(name)) { return; } //如果不允许覆盖,直接抛异常 if (!allowAliasOverriding()) { throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" + name + "': It is already registered for name '" + registeredName + "'."); } } //检查name:a alias:b 和name:b alias:a 是否存在 checkForAliasCircle(name, alias); //都不存在,缓存别名 this.aliasMap.put(alias, name); } } /** * 是否允许覆盖 默认允许 * Default is {@code true}. */ protected boolean allowAliasOverriding() { return true; } /** * 确认给定的bean和别名是否注册,排除循环注册的情况 * @param name the name to check * @param alias the alias to look for * @since 4.2.1 */ public boolean hasAlias(String name, String alias) { for (Map.Entry entry : this.aliasMap.entrySet()) { String registeredName = entry.getValue(); if (registeredName.equals(name)) { String registeredAlias = entry.getKey(); return (registeredAlias.equals(alias) || hasAlias(registeredAlias, alias)); } } return false; } @Override public void removeAlias(String alias) { String name = this.aliasMap.remove(alias); if (name == null) { throw new IllegalStateException("No alias '" + alias + "' registered"); } } @Override public boolean isAlias(String name) { return this.aliasMap.containsKey(name); } @Override public String[] getAliases(String name) { List result = new ArrayList (); synchronized (this.aliasMap) { retrieveAliases(name, result); } return StringUtils.toStringArray(result); } /** * 检索给定name的所有别名,结果放在result中. * @param name the target name to find aliases for * @param result the resulting aliases list */ private void retrieveAliases(String name, List result) { for (Map.Entry entry : this.aliasMap.entrySet()) { String registeredName = entry.getValue(); if (registeredName.equals(name)) { String alias = entry.getKey(); result.add(alias); retrieveAliases(alias, result); } } } /** * 通过StringValueResolver解析别名,并重新注册(例如:别名中包含占位符) * @param valueResolver the StringValueResolver to apply */ public void resolveAliases(StringValueResolver valueResolver) { Assert.notNull(valueResolver, "StringValueResolver must not be null"); synchronized (this.aliasMap) { //copy一份缓存 Map aliasCopy = new HashMap (this.aliasMap); for (String alias : aliasCopy.keySet()) { String registeredName = aliasCopy.get(alias); //获取解析之后的别名 String resolvedAlias = valueResolver.resolveStringValue(alias); //解析之后的name String resolvedName = valueResolver.resolveStringValue(registeredName); //如果别名和name已经注册,就移除,解决循环依赖的问题 if (resolvedAlias == null || resolvedName == null || resolvedAlias.equals(resolvedName)) { this.aliasMap.remove(alias); }else if (!resolvedAlias.equals(alias)) {//解析别名和原别名不同 String existingName = this.aliasMap.get(resolvedAlias); if (existingName != null) {//解析之后的别名和name存在,移除 if (existingName.equals(resolvedName)) { this.aliasMap.remove(alias); break; } //别名相同,name不同抛异常,注册失败 throw new IllegalStateException( "Cannot register resolved alias '" + resolvedAlias + "' (original: '" + alias + "') for name '" + resolvedName + "': It is already registered for name '" + registeredName + "'."); } checkForAliasCircle(resolvedName, resolvedAlias); //删除原来的别名,重新注册 this.aliasMap.remove(alias); this.aliasMap.put(resolvedAlias, resolvedName); } else if (!registeredName.equals(resolvedName)) {//如果名称不相同,直接注册 this.aliasMap.put(alias, resolvedName); } } } } /** * 检查别名和name是否循环注册 * @param name the candidate name * @param alias the candidate alias * @see #registerAlias * @see #hasAlias */ protected void checkForAliasCircle(String name, String alias) { if (hasAlias(alias, name)) { throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" + name + "': Circular reference - '" + name + "' is a direct or indirect alias for '" + alias + "' already"); } } /** * 获取以name为key的name * @param name the user-specified name * @return the transformed name */ public String canonicalName(String name) { String canonicalName = name; // Handle aliasing... String resolvedName; do { resolvedName = this.aliasMap.get(canonicalName); if (resolvedName != null) { canonicalName = resolvedName; } } while (resolvedName != null); return canonicalName; } }
package org.springframework.beans.factory.config; /** * 定义bean的注册、查询服务 * *The {@link ConfigurableBeanFactory} interface extends this interface. * * @author Juergen Hoeller * @since 2.0 * @see ConfigurableBeanFactory * @see org.springframework.beans.factory.support.DefaultSingletonBeanRegistry * @see org.springframework.beans.factory.support.AbstractBeanFactory */ public interface SingletonBeanRegistry { /** * 注册单例bean * @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); /** * 通过name获取一个单例bean对象 * @param beanName the name of the bean to look for * @return the registered singleton object, or {@code null} if none found * @see ConfigurableListableBeanFactory#getBeanDefinition */ Object getSingleton(String beanName); /** * 检查注册表中是否包含该单例bean * @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的名称 * @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(); /** * 获取所有单例bean的数量 * @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 mutex object (never {@code null}) * @since 4.2 */ Object getSingletonMutex(); }
package org.springframework.beans.factory.support; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanCreationNotAllowedException; import org.springframework.beans.factory.BeanCurrentlyInCreationException; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.ObjectFactory; import org.springframework.beans.factory.config.SingletonBeanRegistry; import org.springframework.core.SimpleAliasRegistry; import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** * 默认单例注册表实现 * @author Juergen Hoeller * @since 2.0 * @see #registerSingleton * @see #registerDisposableBean * @see org.springframework.beans.factory.DisposableBean * @see org.springframework.beans.factory.config.ConfigurableBeanFactory */ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { /** * 并发map中不允许空,用空对象代替 */ protected static final Object NULL_OBJECT = new Object(); /** Logger available to subclasses */ protected final Log logger = LogFactory.getLog(getClass()); /** 缓存所有的单例对象: bean name --> bean instance */ private final MapsingletonObjects = new ConcurrentHashMap (256); /** 缓存所有的objectFactory对象: bean name --> ObjectFactory */ private final Map > singletonFactories = new HashMap >(16); /** 获取所有可以提前获取的对象(循环依赖的时候使用): bean name --> bean instance */ private final Map earlySingletonObjects = new HashMap (16); /** 所有已经注册的bean的name列表,有序的 */ private final Set registeredSingletons = new LinkedHashSet (256); /** 所有正在创建的bean的名称 */ private final Set singletonsCurrentlyInCreation =Collections.newSetFromMap(new ConcurrentHashMap (16)); /** 所有被创建检查排除的bean列表 */ private final Set inCreationCheckExclusions =Collections.newSetFromMap(new ConcurrentHashMap (16)); /** bean管理过程中所有的被禁用的异常列表 */ private Set suppressedExceptions; /** 标识当前是否处于销毁单例bean的时候 */ private boolean singletonsCurrentlyInDestruction = false; /** Disposable bean 实例: bean name --> disposable instance */ private final Map disposableBeans = new LinkedHashMap (); /** bean和bean所包含的bean之间的关系: bean name --> Set of bean names that the bean contains */ private final Map > containedBeanMap = new ConcurrentHashMap >(16); /** bean和bean所依赖的bean之间的关系: bean name --> Set of dependent bean names */ private final Map > dependentBeanMap = new ConcurrentHashMap >(64); /** bean和依赖该bean的bean之间的关系: bean name --> 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, "'beanName' must not be null"); synchronized (this.singletonObjects) { //如果该bean已经注册,抛出异常 Object oldObject = this.singletonObjects.get(beanName); if (oldObject != null) { throw new IllegalStateException("Could not register object [" + singletonObject + "] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound"); } addSingleton(beanName, singletonObject); } } /** * 将bean添加到注册表中,singletonObjects、registeredSingletons缓存中添加, * singletonFactories、earlySingletonObjects 缓存中删除 * 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 != null ? singletonObject : NULL_OBJECT)); this.singletonFactories.remove(beanName); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } } /** * 通过一个工厂对象添加一个往注册表中添加一个对象 * @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); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } } } @Override public Object getSingleton(String beanName) { return getSingleton(beanName, true); } /** * 获取一个单例bean对象,是否允许创建之前获取一个对象 * @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 */ protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject = this.singletonObjects.get(beanName); //如果已经创建的bean对象缓存中没有,并且当前bean正在创建 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { //从可以提前获取的单例对象缓存中查找对象 singletonObject = this.earlySingletonObjects.get(beanName); //如果没有创建,并且允许提前获取对象 if (singletonObject == null && allowEarlyReference) { //就从工厂bean缓存中获取bean的工厂类 ObjectFactory> singletonFactory = this.singletonFactories.get(beanName); //如果工厂类不为空,就通过工厂类创建一个单例对象,并将该单例对象放到提前获取的单例缓存中, //并从工厂bean缓存中移除 if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return (singletonObject != NULL_OBJECT ? singletonObject : null); } /** * 通过一个工厂bean获取一个bean对象 * @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, "'beanName' 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 + "'"); } //bean的前处理器 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; } //bean的后处理器 afterSingletonCreation(beanName); } if (newSingleton) { addSingleton(beanName, singletonObject); } } return (singletonObject != NULL_OBJECT ? singletonObject : null); } } /** * 存放bean创建过程的异常 * @param ex the Exception to register */ protected void onSuppressedException(Exception ex) { synchronized (this.singletonObjects) { if (this.suppressedExceptions != null) { this.suppressedExceptions.add(ex); } } } /** * 移除一个单例bean * @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"); 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) { if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) { throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation"); } } /** * 注册一个可销毁的bean * @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); } } /** * 注册一个包含内部bean和外部bean的bean对象 * @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) { // A quick check for an existing entry upfront, avoiding synchronization... Set
containedBeans = this.containedBeanMap.get(containingBeanName); if (containedBeans != null && containedBeans.contains(containedBeanName)) { return; } // No entry yet -> fully synchronized manipulation of the containedBeans Set synchronized (this.containedBeanMap) { containedBeans = this.containedBeanMap.get(containingBeanName); if (containedBeans == null) { containedBeans = new LinkedHashSet (8); this.containedBeanMap.put(containingBeanName, containedBeans); } containedBeans.add(containedBeanName); } registerDependentBean(containedBeanName, containingBeanName); } /** * 注册一个bean和他依赖的bean * @param beanName the name of the bean * @param dependentBeanName the name of the dependent bean */ public void registerDependentBean(String beanName, String dependentBeanName) { // A quick check for an existing entry upfront, avoiding synchronization... String canonicalName = canonicalName(beanName); Set dependentBeans = this.dependentBeanMap.get(canonicalName); if (dependentBeans != null && dependentBeans.contains(dependentBeanName)) { return; } // No entry yet -> fully synchronized manipulation of the dependentBeans Set synchronized (this.dependentBeanMap) { dependentBeans = this.dependentBeanMap.get(canonicalName); if (dependentBeans == null) { dependentBeans = new LinkedHashSet (8); this.dependentBeanMap.put(canonicalName, dependentBeans); } dependentBeans.add(dependentBeanName); } synchronized (this.dependenciesForBeanMap) { Set dependenciesForBean = this.dependenciesForBeanMap.get(dependentBeanName); if (dependenciesForBean == null) { dependenciesForBean = new LinkedHashSet (8); this.dependenciesForBeanMap.put(dependentBeanName, dependenciesForBean); } dependenciesForBean.add(canonicalName); } } /** * 判断两个bean是否相互依赖 * @param beanName the name of the bean to check * @param dependentBeanName the name of the dependent bean * @since 4.0 */ protected boolean isDependent(String beanName, String dependentBeanName) { return isDependent(beanName, dependentBeanName, null); } private boolean isDependent(String beanName, String dependentBeanName, Set alreadySeen) { if (alreadySeen != null && alreadySeen.contains(beanName)) { return false; } String canonicalName = canonicalName(beanName); Set dependentBeans = this.dependentBeanMap.get(canonicalName); if (dependentBeans == null) { return false; } if (dependentBeans.contains(dependentBeanName)) { return true; } for (String transitiveDependency : dependentBeans) { if (alreadySeen == null) { alreadySeen = new HashSet (); } alreadySeen.add(beanName); if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) { return true; } } return false; } /** * 确认当前bean是否有依赖 * @param beanName the name of the bean to check */ protected boolean hasDependentBean(String beanName) { return this.dependentBeanMap.containsKey(beanName); } /** * 获取这个bean所有依赖的bean * @param beanName the name of the bean * @return the array of dependent bean names, or an empty array if none */ public String[] getDependentBeans(String beanName) { Set dependentBeans = this.dependentBeanMap.get(beanName); if (dependentBeans == null) { return new String[0]; } return StringUtils.toStringArray(dependentBeans); } /** * 返回所有依赖该bean的bean对象 * @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 */ public String[] getDependenciesForBean(String beanName) { Set dependenciesForBean = this.dependenciesForBeanMap.get(beanName); if (dependenciesForBean == null) { return new String[0]; } return dependenciesForBean.toArray(new String[dependenciesForBean.size()]); } public void destroySingletons() { if (logger.isDebugEnabled()) { logger.debug("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(); 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; synchronized (this.disposableBeans) { disposableBean = (DisposableBean) this.disposableBeans.remove(beanName); } destroyBean(beanName, disposableBean); } /** * 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, DisposableBean bean) { // Trigger destruction of dependent beans first... Set dependencies = this.dependentBeanMap.remove(beanName); if (dependencies != null) { if (logger.isDebugEnabled()) { logger.debug("Retrieved dependent beans for bean '" + beanName + "': " + dependencies); } for (String dependentBeanName : dependencies) { destroySingleton(dependentBeanName); } } // Actually destroy the bean now... if (bean != null) { try { bean.destroy(); } catch (Throwable ex) { logger.error("Destroy method on bean with name '" + beanName + "' threw an exception", ex); } } // Trigger destruction of contained beans... Set containedBeans = this.containedBeanMap.remove(beanName); if (containedBeans != null) { for (String containedBeanName : containedBeans) { destroySingleton(containedBeanName); } } // 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(); } } } // 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; } }