寫在前面:趁着寒假尾聲整理了一波上學期自己的Java源碼筆記總結,把一篇篇小筆記總結成文章,系統性的轉到博客,這樣的年度總結希望能對同好們有幫助
1.單例模式理解
確保某一個類只有一個實例,而且提供全局訪問點實例化並向整個系統提供這個實例,這個類稱爲單例類(Spring提供的訪問點是beanFactory)
2.單例模式的要點有三個
一是某個類只能有一個實例;
二是它必須自行創建這個實例;
三是它必須自行向整個系統提供這個實例。
3.ErrorContext的單例實現代碼:
//具有一個static的局部instance變量和一個獲取instance變量的方法
public class ErrorContext {
//有趣的地方是,LOCAL的靜態實例變量使用了ThreadLocal修飾,也就是說它屬於每個線程各自的數據
private static final ThreadLocal<ErrorContext> LOCAL = new ThreadLocal<ErrorContext>();
//構造函數是private修飾
private ErrorContext() {
}
//而在instance()方法中,先獲取本線程的該實例,如果沒有就創建該線程獨有的ErrorContext
public static ErrorContext instance() {
ErrorContext context = LOCAL.get();
if (context == null) {
context = new ErrorContext();
LOCAL.set(context);
}
return context;
}
2.getSingleton一路跟蹤下去,發現實際上是調用了 AbstractAutowireCapableBeanFactory 的 doCreateBean 方法,返回了BeanWrapper包裝並創建的bean實例。
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//從緩存singletonObjects(實際上是一個map)中獲取bean實例
Object singletonObject = this.singletonObjects.get(beanName);
//如果爲null,對緩存singletonObjects加鎖,然後再從緩存中獲取bean,如果繼續爲null,就創建一個bean。
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
Map var4 = this.singletonObjects;
//雙重判斷加鎖
synchronized(this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//通過 singletonFactory.getObject() 返回具體beanName對應的ObjectFactory來創建bean。
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
} } }