常用開(kāi)源框架中設(shè)計(jì)模式使用分析-單例設(shè)計(jì)模式(Singleton Pattern)

四、單例設(shè)計(jì)模式(Singleton Pattern)

4.1 介紹

阿里巴巴長(zhǎng)期招聘Java研發(fā)工程師p6,p7,p8等上不封頂級(jí)別,有意向的可以發(fā)簡(jiǎn)歷給我,注明想去的部門(mén)和工作地點(diǎn):1064454834@qq.com

歡迎關(guān)注微信公眾號(hào):技術(shù)原始積累 獲取更多技術(shù)干貨

單例模式是一種創(chuàng)建型模式,單例模式提供一個(gè)創(chuàng)建對(duì)象的接口,但是多次調(diào)用該接口返回的是同一個(gè)實(shí)例的引用,目的是為了保證只有一個(gè)實(shí)例,并且提供一個(gè)訪問(wèn)這個(gè)實(shí)例的統(tǒng)一接口。

4.2 Spring中單例bean的創(chuàng)建

Spring中默認(rèn)配置的bean的scope為singleton,也就是單例作用域。那么看看它是如何做到的。
在AbstractBeanFactory類里面的doGetBean方法:

protected Object doGetBean(
            final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {

    final String beanName = transformedBeanName(name);
    Object bean = null;

    // 解決set循環(huán)依賴
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        ...
    }

    else {
        ...
        // 創(chuàng)建單件bean.
        if (mbd.isSingleton()) {
            sharedInstance = getSingleton(beanName, new ObjectFactory() {
                public Object getObject() throws BeansException {
                    try {
                        return createBean(beanName, mbd, args);
                    }
                    catch (BeansException ex) {
                    ...
                        throw ex;
                    }
                }
            });
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
        }
       //創(chuàng)建原型bean
        else if (mbd.isPrototype()) {
            ...
        }
        //創(chuàng)建request作用域bean
        else {
            ...
        }
    }
            ...
    return bean;
}

getSingleton代碼:

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) {
            ...
            beforeSingletonCreation(beanName);
            ...
            try {
                singletonObject = singletonFactory.getObject();
            }
            catch (BeanCreationException ex) {
                ...
            }
            finally {
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = null;
                }
                afterSingletonCreation(beanName);
            }
            addSingleton(beanName, singletonObject);
        }
        return (singletonObject != NULL_OBJECT ? singletonObject : null);
    }
}

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);
    }
}

private final Map singletonObjects = CollectionFactory.createConcurrentMapIfPossible(16);

可知Spring內(nèi)部四通過(guò)一個(gè)ConcurrentMap來(lái)管理單件bean的。獲取bean時(shí)候會(huì)先看看singletonObjects中是否有,有則直接返回,沒(méi)有則創(chuàng)建后放入。

看個(gè)時(shí)序圖:


image.png

Spring的bean工廠管理的單例模式管理的是多個(gè)bean實(shí)例的單例,是工廠模式管理所有的bean,而每個(gè)bean的創(chuàng)建又使用了單例模式。

4.4 使用場(chǎng)景

  • 同一個(gè)jvm應(yīng)用的不同模塊需要使用同一個(gè)對(duì)象實(shí)例進(jìn)行信息共享。
  • 需要同一個(gè)實(shí)例來(lái)生成全局統(tǒng)一的序列號(hào)

歡迎關(guān)注微信公眾號(hào):技術(shù)原始積累 獲取更多技術(shù)干貨

image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,569評(píng)論 19 139
  • 文章作者:Tyan博客:noahsnail.com 3.4 Dependencies A typical ente...
    SnailTyan閱讀 4,493評(píng)論 2 7
  • 什么是Spring Spring是一個(gè)開(kāi)源的Java EE開(kāi)發(fā)框架。Spring框架的核心功能可以應(yīng)用在任何Jav...
    jemmm閱讀 16,773評(píng)論 1 133
  • 文章作者:Tyan博客:noahsnail.com 3.5 Bean scopes When you create...
    SnailTyan閱讀 2,003評(píng)論 0 1
  • 從圖書(shū)館旁邊搬走,心里有萬(wàn)分的不舍。以后看書(shū)借書(shū)就沒(méi)有之前那么方便了,我暗下決心以后不管多忙,每個(gè)月至少要去兩次。...
    米蘇聞閱讀 290評(píng)論 2 3

友情鏈接更多精彩內(nèi)容