Spring源码阅读之DefaultListableBeanFactory系列-DefaultSingletonBeanRegistry

本文深入剖析了Spring框架中DefaultSingletonBeanRegistry类的功能与实现,包括单例对象的注册、获取与销毁流程,并详细解释了相关缓存机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

DefaultSingletonBeanRegistry是接口SingletonBeanRegistry的具体实现,实现了对单例的注册及获取等相关操作。

相关源码分析:

/**
 * 单例注册、获取等具体实现
 */
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {

    /**
     * 内部使用,由于Spring内部不支持null,用该常量表示空的单例对象
     */
    protected static final Object NULL_OBJECT = new Object();

    protected final Log logger = LogFactory.getLog(getClass());

    /**
     * 单例对象缓存,key:beanName value:instance
     */
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);

    /**
     * 单例工厂缓存,key:beanName value:ObjectFactory
     */
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);

    /**
     * early单例对象缓存(不是很明白什么叫early singleton),key:beanName value:instance
     */
    private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);

    /**
     * 已经注册的单例集合,包括注册队列里bean的name
     */
    private final Set<String> registeredSingletons = new LinkedHashSet<String>(256);

    /**
     * 目前正在创建的bean的name列表
     */
    private final Set<String> singletonsCurrentlyInCreation =
            Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));

    /**
     * 目前正在从创建检查中移除的bean的name列表
     */
    private final Set<String> inCreationCheckExclusions =
            Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));

    /**
     * suppressed exception列表
     */
    private Set<Exception> suppressedExceptions;

    /**
     * 所有单例当前是否正在被销毁
     */
    private boolean singletonsCurrentlyInDestruction = false;

    /**
     * 一次性使用的单例对象缓存,key:beanName value:instance
     */
    private final Map<String, Object> disposableBeans = new LinkedHashMap<String, Object>();

    /**
     * key:beanName value:bean包含的bean name列表
     */
    private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<String, Set<String>>(16);

    /**
     * key:beanName value:bean依赖的bean name列表
     */
    private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>(64);

    /**
     * key:beanName value:bean依赖的beans' names列表
     */
    private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<String, Set<String>>(64);

    /**
     * 单例注册
     * @param beanName beanName
     * @param singletonObject 类的实例
     * @throws IllegalStateException
     */
    @Override
    public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
        //参数校验
        Assert.notNull(beanName, "'beanName' must not be null");
        synchronized (this.singletonObjects) {
            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配置一个实例
     * @param beanName
     * @param singletonObject
     */
    protected void addSingleton(String beanName, Object singletonObject) {
        synchronized (this.singletonObjects) {
            this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
            //注册单例成功后从单例工厂缓存中移除
            this.singletonFactories.remove(beanName);
            //注册单例成功后从early singleton缓存中移除
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.add(beanName);
        }
    }

    /**
     * 在单例工厂中为该bean创建一个工厂,这一步骤在注册单例之前完成
     * @param beanName
     * @param singletonFactory
     */
    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);
            }
        }
    }

    /**
     * 根据beanName获取单例
     * @param beanName bean name
     * @return instance
     */
    @Override
    public Object getSingleton(String beanName) {
        return getSingleton(beanName, true);
    }

    /**
     * 根据beanName获取单例
     * 大致几个步骤:
     * 1.先从单例对象的缓存中取,假如能取到说明当前bean已经有单例了,直接取出来即可;
     * 2.从单例对象缓存中取不到,说明该bean正在创建或者没有完成创建:
     *   1)如果bean正在创建,去early singleton缓存中取(在注册成功之前,early singleton和beanFactory已经初始化好),
     *      能从early singleton中取到,直接返回,假如取不到,说明该bean还在单例工厂阶段,假如允许注册前可以被引用,可以
     *      直接去单例工厂取,无需等到注册完毕之后再取;
     *   2)如果bean并没有完成创建,之间返回null。
     * 5.前面几个步骤都没有取到,说明该bean没有单例,返回null
     * @param beanName bean name
     * @param allowEarlyReference instance
     * @return
     */
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        //从单例对象缓存中取出instance
        Object singletonObject = this.singletonObjects.get(beanName);
        //instance为null或者该bean正在创建单例
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
                //可以从early singleton缓存中取
                singletonObject = this.earlySingletonObjects.get(beanName);
                //early singleton中取到的instance还是为空
                if (singletonObject == null && allowEarlyReference) {
                    //取该bean的单例工厂,从工厂中取instance
                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        singletonObject = singletonFactory.getObject();
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return (singletonObject != NULL_OBJECT ? singletonObject : null);
    }

    /**
     * 从bean的单例工厂中获取instance
     * @param beanName bean name
     * @param singletonFactory 单例工厂
     * @return instance
     */
    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 the 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<Exception>();
                }
                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) {
                    addSingleton(beanName, singletonObject);
                }
            }
            return (singletonObject != NULL_OBJECT ? singletonObject : null);
        }
    }

    protected void onSuppressedException(Exception ex) {
        synchronized (this.singletonObjects) {
            if (this.suppressedExceptions != null) {
                this.suppressedExceptions.add(ex);
            }
        }
    }

    /**
     * 移除bean的单例,实质上是移除几个缓存里面该bean对应的数据
     * @param beanName bean name
     */
    protected void removeSingleton(String beanName) {
        synchronized (this.singletonObjects) {
            this.singletonObjects.remove(beanName);
            this.singletonFactories.remove(beanName);
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.remove(beanName);
        }
    }

    /**
     * 判断该bean是否已经有注册的单例
     * @param beanName bean name
     * @return
     */
    @Override
    public boolean containsSingleton(String beanName) {
        return this.singletonObjects.containsKey(beanName);
    }

    /**
     * 获取所有已注册单例的bean的name
     * @return
     */
    @Override
    public String[] getSingletonNames() {
        synchronized (this.singletonObjects) {
            return StringUtils.toStringArray(this.registeredSingletons);
        }
    }

    /**
     * 计算已注册的单例数量
     * @return
     */
    @Override
    public int getSingletonCount() {
        synchronized (this.singletonObjects) {
            return this.registeredSingletons.size();
        }
    }

    /**
     * 设置bean是否正在创建
     * @param beanName bean name
     * @param inCreation 是否正在创建
     */
    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);
        }
    }

    /**
     * 判断bean instance是否正在被创建
     * @param beanName
     * @return
     */
    public boolean isCurrentlyInCreation(String beanName) {
        //参数校验
        Assert.notNull(beanName, "Bean name must not be null");
        return (!this.inCreationCheckExclusions.contains(beanName) && isActuallyInCreation(beanName));
    }

    /**
     * 判断bean instance是否正在被创建
     * @param beanName bean name
     * @return
     */
    protected boolean isActuallyInCreation(String beanName) {
        return isSingletonCurrentlyInCreation(beanName);
    }

    public boolean isSingletonCurrentlyInCreation(String beanName) {
        return this.singletonsCurrentlyInCreation.contains(beanName);
    }

    /**
     * 判断bean是否在创建instance之前
     * @param beanName
     */
    protected void beforeSingletonCreation(String beanName) {
        if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }
    }

    /**
     * 判断bean是否在创建instance之后
     * @param beanName
     */
    protected void afterSingletonCreation(String beanName) {
        if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
            throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
        }
    }

    /**
     * 注册一次性使用的单例
     * @param beanName
     * @param bean
     */
    public void registerDisposableBean(String beanName, DisposableBean bean) {
        synchronized (this.disposableBeans) {
            this.disposableBeans.put(beanName, bean);
        }
    }

    /**
     * 注册两个bean之间的一个包含关系
     * @param containedBeanName
     * @param containingBeanName
     */
    public void registerContainedBean(String containedBeanName, String containingBeanName) {
        // A quick check for an existing entry upfront, avoiding synchronization...
        Set<String> 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<String>(8);
                this.containedBeanMap.put(containingBeanName, containedBeans);
            }
            containedBeans.add(containedBeanName);
        }
        //注册依赖
        registerDependentBean(containedBeanName, containingBeanName);
    }

    /**
     * 为bean注册一个依赖的bean
     * @param beanName bean name
     * @param dependentBeanName 依赖的bean name
     */
    public void registerDependentBean(String beanName, String dependentBeanName) {
        // A quick check for an existing entry upfront, avoiding synchronization...
        String canonicalName = canonicalName(beanName);
        //是否已经有依赖的bean,有的话不需要再注册
        Set<String> 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<String>(8);
                this.dependentBeanMap.put(canonicalName, dependentBeans);
            }
            dependentBeans.add(dependentBeanName);
        }
        synchronized (this.dependenciesForBeanMap) {
            Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(dependentBeanName);
            if (dependenciesForBean == null) {
                dependenciesForBean = new LinkedHashSet<String>(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
     * @return
     */
    protected boolean isDependent(String beanName, String dependentBeanName) {
        return isDependent(beanName, dependentBeanName, null);
    }
    
    private boolean isDependent(String beanName, String dependentBeanName, Set<String> alreadySeen) {
        String canonicalName = canonicalName(beanName);
        if (alreadySeen != null && alreadySeen.contains(beanName)) {
            return false;
        }
        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<String>();
            }
            alreadySeen.add(beanName);
            if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否已经有被注册的依赖关系的bean
     * @param beanName the name of the bean to check
     * @return
     */
    protected boolean hasDependentBean(String beanName) {
        return this.dependentBeanMap.containsKey(beanName);
    }

    public String[] getDependentBeans(String beanName) {
        Set<String> dependentBeans = this.dependentBeanMap.get(beanName);
        if (dependentBeans == null) {
            return new String[0];
        }
        return StringUtils.toStringArray(dependentBeans);
    }

    /**
     * 获取所有有依赖关系的bean
     * @param beanName the name of the bean to check
     * @return
     */
    public String[] getDependenciesForBean(String beanName) {
        Set<String> 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);
        }
        //将正在销毁单例这个标志符置为true
        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;
        }
    }

    /**
     * 销毁某个bean的单例
     * @param beanName 待销毁的bean name
     */
    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);
    }

    /**
     * 销毁bean,在销毁之前需要销毁所有跟它有依赖关系的bean
     * @param beanName bean name
     * @param bean 待销毁的bean instance
     */
    protected void destroyBean(String beanName, DisposableBean bean) {
        // Trigger destruction of dependent beans first...
        Set<String> dependencies = this.dependentBeanMap.remove(beanName);
        if (dependencies != null) {
            if (logger.isDebugEnabled()) {
                logger.debug("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
            }
            //销毁有依赖关系的bean
            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<String> 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();
                }
            }
        }

        // Remove destroyed bean's prepared dependency information.
        this.dependenciesForBeanMap.remove(beanName);
    }

    public final Object getSingletonMutex() {
        return this.singletonObjects;
    }
}
整个类着重实现了单例模式从注册,到使用,再到销毁这个过程,代码可读性还是很强的。

可能整个逻辑比较复杂的就是根据bean name获取该bean的实例,具体的获取步骤已经在注释中详细的给出,分哪些情况,从哪些缓存中取,在此不做更详细的赘述了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值