Spring DefaultSingletonBeanRegistry 类,源码阅读记录
package com.geely.online.testdriver; import org.springframework.beans.factory.*; import org.springframework.beans.factory.config.SingletonBeanRegistry; import org.springframework.core.SimpleAliasRegistry; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import java.util.*; import java.util.concurrent.ConcurrentHashMap; /** * 单例bean注册器,通过beanName获取 * <p> * Generic registry for shared bean instances, implementing the * {@link org.springframework.beans.factory.config.SingletonBeanRegistry}. * Allows for registering singleton instances that should be shared * for all callers of the registry, to be obtained via bean name. * * * <p>Also supports registration of * {@link org.springframework.beans.factory.DisposableBean} instances, * (which might or might not correspond to registered singletons), * to be destroyed on shutdown of the registry. Dependencies between * beans can be registered to enforce an appropriate shutdown order. * <p> * <p> * // 当前类主要作为BeanFactory 的基础实现类 * <p>This class mainly serves as base class for * {@link org.springframework.beans.factory.BeanFactory} implementations, * factoring out the common management of singleton bean instances. Note that * the {@link org.springframework.beans.factory.config.ConfigurableBeanFactory} * interface extends the {@link SingletonBeanRegistry} interface. * <p> * 这个类,既没有beand定义信息,也没有bean创建过程 * <p>Note that this class assumes neither a bean definition concept * nor a specific creation process for bean instances, in contrast to * {@link AbstractBeanFactory} and {@link DefaultListableBeanFactory} * (which inherit from it). Can alternatively also be used as a nested * helper to delegate to. * * @author Juergen Hoeller * @see #registerSingleton * @see #registerDisposableBean * @see org.springframework.beans.factory.DisposableBean * @see org.springframework.beans.factory.config.ConfigurableBeanFactory * @since 2.0 */ //单实例对象注册器 (DefaultSingletonBeanRegistry) public class MyDefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { /** * Maximum number of suppressed exceptions to preserve. */ //最大数量异常 private static final int SUPPRESSED_EXCEPTIONS_LIMIT = 100; /** * Cache of singleton objects: bean name to bean instance. */ //单例对象缓存 private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); /** * Cache of singleton factories: bean name to ObjectFactory. */ //单例对象创建工厂缓存 private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); /** * Cache of early singleton objects: bean name to bean instance. */ //早产单例对象缓存 private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16); /** * Set of registered singletons, containing the bean names in registration order. */ //注册的单例对象,按照注册顺序排序 private final Set<String> registeredSingletons = new LinkedHashSet<>(256); /** * Names of beans that are currently in creation. */ //当前时刻正在创建的bean名称 private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16)); /** * Names of beans currently excluded from in creation checks. */ //当前时刻正在创建的不用校验的 private final Set<String> inCreationCheckExclusions = Collections.newSetFromMap(new ConcurrentHashMap<>(16)); /** * Disposable bean instances: bean name to disposable instance. */ //一次性的bean private final Map<String, Object> disposableBeans = new LinkedHashMap<>(); /** * Map between containing bean names: bean name to Set of bean names that the bean contains. */ //已经包含的bean private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16); /** * Map between dependent bean names: bean name to Set of dependent bean names. */ //当前这个bean的被依赖情况 private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64); /** * Map between depending bean names: bean name to Set of bean names for the bean's dependencies. */ //当前这个bean的依赖 private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64); /** * Collection of suppressed Exceptions, available for associating related causes. */ @Nullable //被抑制的异常信息 private Set<Exception> suppressedExceptions; /** * Flag that indicates whether we're currently within destroySingletons. */ //单实例当前正在被销毁 private boolean singletonsCurrentlyInDestruction = false; //注册一个单实例对象到注册器中(一级缓存,singletonObjects) @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) { //当前这个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); } } /** * Add the given singleton object to the singleton cache of this factory. * <p>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); //从 单例对象工厂集 移除 this.singletonFactories.remove(beanName); //从 早产单例对象集 移除 this.earlySingletonObjects.remove(beanName); //添加到 已注册单例对象集 this.registeredSingletons.add(beanName); } } /** * Add the given singleton factory for building the specified singleton * if necessary. * <p>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); //从 早产单例对象集 移除 this.earlySingletonObjects.remove(beanName); //添加到 已注册单例对象集 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. * <p>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) { // Quick check for existing instance without full singleton lock Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { synchronized (this.singletonObjects) { //一致性创建一个可提早引用的对象,通过锁 // Consistent creation of early reference within full singleton lock //1级缓存,singletonObjects (单例对象集) singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { //2级缓存,earlySingletonObjects (早产单例对象集) singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null) { //3级缓存,单例对象工厂集 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) { //bean创建不被允许异常 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); } //如果创建里一个单例,将单例加到单例对象集中 if (newSingleton) { //加到一级缓存,清除2、3级缓存 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. * <p>The default implementation preserves any given exception in this registry's * collection of suppressed exceptions, up to a limit of 100 exceptions, adding * them as related causes to an eventual top-level {@link BeanCreationException}. * * @param ex the Exception to register * @see BeanCreationException#getRelatedCauses() */ //抑制异常(把异常塞到容器中) protected void onSuppressedException(Exception ex) { synchronized (this.singletonObjects) { if (this.suppressedExceptions != null && this.suppressedExceptions.size() < SUPPRESSED_EXCEPTIONS_LIMIT) { 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() */ //移除单例,从1单例集,2早期单例集,3单例工厂集,已注册单例集中 移除 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(); } } //设置这个bean当前时刻是否在创建中... 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. * <p>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) { //正在创建对象不用校验集,不存在这个bean (这个bean需要校验) //加入到单例当前正在生成中失败时 if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) { //报错,当前bean正在被创建了... throw new BeanCurrentlyInCreationException(beanName); } } /** * Callback after singleton creation. * <p>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"); } } /** * Add the given bean to the list of disposable beans in this registry. * <p>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. * <p>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) { Set<String> containedBeans = this.containedBeanMap.computeIfAbsent(containingBeanName, k -> new LinkedHashSet<>(8)); 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); synchronized (this.dependentBeanMap) { Set<String> dependentBeans = this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8)); if (!dependentBeans.add(dependentBeanName)) { return; } } synchronized (this.dependenciesForBeanMap) { Set<String> 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 */ protected boolean isDependent(String beanName, String dependentBeanName) { synchronized (this.dependentBeanMap) { return isDependent(beanName, dependentBeanName, null); } } private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) { if (alreadySeen != null && alreadySeen.contains(beanName)) { return false; } String canonicalName = canonicalName(beanName); Set<String> 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; } /** * Determine whether a dependent bean has been registered for the given name. * * @param beanName the name of the bean to check */ 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 */ public String[] getDependentBeans(String beanName) { Set<String> 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 */ public String[] getDependenciesForBean(String beanName) { Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(beanName); if (dependenciesForBean == null) { return new String[0]; } synchronized (this.dependenciesForBeanMap) { return StringUtils.toStringArray(dependenciesForBean); } } 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); // 销毁相关的一次性bean // 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 */ //销毁bean protected void destroyBean(String beanName, @Nullable DisposableBean bean) { // Trigger destruction of dependent beans first... //触发依赖我的那些bean (dependent),执行销毁 Set<String> dependencies; synchronized (this.dependentBeanMap) { // Within full synchronization in order to guarantee a disconnected Set dependencies = this.dependentBeanMap.remove(beanName); } if (dependencies != null) { if (logger.isTraceEnabled()) { logger.trace("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) { if (logger.isWarnEnabled()) { logger.warn("Destruction of bean with name '" + beanName + "' threw an exception", ex); } } } // Trigger destruction of contained beans... Set<String> containedBeans; synchronized (this.containedBeanMap) { // Within full synchronization in order to guarantee a disconnected Set //这个beanName中包含的beanNames 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<Map.Entry<String, Set<String>>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext(); ) { Map.Entry<String, Set<String>> entry = it.next(); Set<String> dependenciesToClean = entry.getValue(); dependenciesToClean.remove(beanName); if (dependenciesToClean.isEmpty()) { it.remove(); } } } // 从容器中删除自己,去掉被我依赖beanName的信息 // Remove destroyed bean's prepared dependency information. this.dependenciesForBeanMap.remove(beanName); } /** * Exposes the singleton mutex to subclasses and external collaborators. * <p>Subclasses should synchronize on the given Object if they perform * any sort of extended singleton creation phase. In particular, subclasses * should <i>not</i> have their own mutexes involved in singleton creation, * to avoid the potential for deadlocks in lazy-init situations. */ @Override public final Object getSingletonMutex() { return this.singletonObjects; } }