spring中的單例模式

spring依賴注入的bean默認都是單例模式,他們是怎麼建立的?spring

在AbstractBeanFactory類中的getBean方法中調用了getSingleton()方法來建立bean:緩存

@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
   Object singletonObject = this.singletonObjects.get(beanName);
   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
      synchronized (this.singletonObjects) {
         singletonObject = this.earlySingletonObjects.get(beanName);
         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;
}

spring依賴注入時,使用了雙重判斷加鎖的單例模式,首先從緩存MAP中獲取bean實例,若是爲null,對緩存map加鎖,而後再從緩存中獲取bean,若是繼續爲null,就建立一個bean。安全

Spring並無使用私有構造方法來建立bean,而是經過singletonFactory.getObject()返回具體beanName對應的ObjectFactory來建立bean。其實是調用了AbstractAutowireCapableBeanFactory的doCreateBean方法,返回了BeanWrapper包裝並建立的bean實例。併發

看一下Netty實現的單例模式app

public final class ReadTimeoutException extends TimeoutException {
    private static final long serialVersionUID = 169287984113283421L;

    public static final ReadTimeoutException INSTANCE = new ReadTimeoutException();

    private ReadTimeoutException() { }
}

類的定義十分簡單,包含一個私有的構造函數和一個static final 實例 :這樣其餘的調用者若是想獲取一個這個類的對象的話,訪問不到私有的構造函數,而只能經過instance拿到對象。函數

使用static final的好處是:當類被調用的時候,static final會初始化,JNI會給這個類添加一個同步塊,保證併發安全。this

另外這種方式只有當類被調用的時候纔會初始化一個實例。對象

相關文章
相關標籤/搜索