這個class是個比較關鍵的類,它也是後面的完成工廠所繼承的頂級class,主要就是實現別名註冊接口和單例註冊接口,從而提供這些服務。緩存
//抑制異常最多100個 private static final int SUPPRESSED_EXCEPTIONS_LIMIT = 100; //一級緩存,緩存beanName和bean實例 private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); //二級緩存,緩存beanName和單例工廠 private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); //三級緩存,緩存beanName和提早暴露的bean實例 private final Map<String, Object> earlySingletonObjects = new HashMap<>(16); //已註冊的單例集合 private final Set<String> registeredSingletons = new LinkedHashSet<>(256); //當前正在建立的單例名字集合 private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16)); //建立檢測時須要排除的bean的名字集合 private final Set<String> inCreationCheckExclusions = Collections.newSetFromMap(new ConcurrentHashMap<>(16)); //已抑制的異常的集合 @Nullable private Set<Exception> suppressedExceptions; //標識是否當前處於銷燬單例過程 private boolean singletonsCurrentlyInDestruction = false; //可銷燬的bean實例 private final Map<String, Object> disposableBeans = new LinkedHashMap<>(); //bean和它包含的bean之間的map private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16); //bean和依賴它的bean之間的map private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64); //bean和它依賴的bean之間的map,注意與上面的區別 private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException { 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); } }
下面是真正作事情的方法,它會在一級緩存裏面添加數據,其餘緩存通通刪除this
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); } }
這裏爲什麼要用倆個synchronized關鍵字?最外層的保留不就好了?設計
返回一個單例,注意這裏有個參數是否容許提早暴露一個實例化完成,但初始化未完成的bean,之因此要這樣設計是爲了解決循環引用問題,這個問題很簡單,就是beanA依賴beanB,beanB依賴beanA若是每一個都去等待另外一個bean建立完成就會陷入死循環中。code
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; }