1. 程式人生 > 其它 >SingletonBeanRegistry(單例 Bean 註冊)介面

SingletonBeanRegistry(單例 Bean 註冊)介面

這個介面就是用來註冊和獲取單例 bean 的,ConfigurableBeanFactory 介面擴充套件了這個介面,這樣做是為了暴露註冊單例 bean 的功能,你可以通過 Spring 容器手動註冊單例 Bean。

這個介面下面有以下方法:


DefaultSingletonBeanRegistry

這個類是 SingletonBeanRegistry 介面的預設實現,也支援註冊 DisposableBean 例項,該類解決 Bean 依賴問題、Bean 迴圈引用問題、Bean 正在建立中問題。

注意:該類的中的方法是執行緒安全的,使用的是 synchronized。

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {

registerSingleton

如果我們要手動向 Spring 容器中直接新增單例 bean 可以使用這個方法,這個方法是將 "singletonObject" 指定的物件做為單例 bean 註冊到 "beanName" 下;但是,在 Spring 容器內部,並不是呼叫這個方法來完成單例 bean 註冊。

void registerSingleton(String beanName, Object singletonObject);

執行流程:

  1. 直接從單例 bean 的快取中通過 "beanName" 獲取 bean 例項。注意:單例 bean 的快取是 ConcurrentHashMap 型別,快取名稱叫 singletonObjects(也叫單例池),裡面快取了 bean 名稱和單例 bean 例項的對映。
  2. 獲取到了就會丟擲 IllegalStateException(非法狀態異常),說明 "beanName" 下面已經註冊了單例 bean,沒有辦法再註冊了。
  3. 沒有獲取到就會將 "beanName" 做為 key,"singletonObject" 做為 value 新增到單例 bean 的快取中,同時移除 singletonFactories 和 earlySingletonObjects 快取中的 "beanName",並將已經註冊好的單例 bean 名稱快取(儲存在 LinkedHashSet 中,單例 bean 名稱按註冊順序排列)。

注意:

  1. "singletonObject" 例項必須是最終的,最終的意思並不是說這個類使用 final 關鍵字修飾,而是說你的這個物件所依賴的其它物件都已經例項化了並且關聯了依賴,當 "singletonObject" 例項獲取出來就能直接使用;也就是說 registerSingleton 方法不會幫你解決依賴問題。
  2. 不會執行 InitializingBean#afterPropertiesSet 方法(初始化回撥)和 DisposableBean#destroy 方法(銷燬回撥)。如果你想執行這兩個回撥方法,應該註冊 BeanDefinition。

getSingleton

通過指定的 "beanName" 返回單例 bean 物件,這個方法只會獲取到已經例項化的單例 bean。

Object getSingleton(String beanName);

執行流程:

注意:

  1. 這個方法可以獲取到 registerSingleton 註冊的單例 bean 和 BeanDefinition 的單例 bean。
  2. 這個方法不支援 FactoryBean 的字首或 bean 的別名。

值得注意的是:這一塊挺不好理解的,可以先看下面的 擴充套件知識點—Spring Bean 快取


SingletonBeanRegistry 介面的其它方法

這個介面剩下了 containsSingleton、getSingletonNames、getSingletonCount 這三個方法;沒有必要去看這三個方法的具體實現,需要記住的是:

  1. 它們使用的都是單例 bean 的快取(singletonObjects),也就是說這三個方法只會判斷被例項化的單例 bean。
  2. 單例 bean 的快取(singletonObjects)中儲存了 registerSingleton 註冊的單例 bean 和 BeanDefinition 已經例項化了的單例 bean。

getSingleton(String, ObjectFactory<?>)

這個方法是 DefaultSingletonBeanRegistry 類新增的方法。該方法也是通過 "beanName" 獲取單例 bean,但是當獲取不到單例 bean 時,會通過 "singletonFactory" 建立單例 bean 並返回。

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {

執行流程:


擴充套件知識點—Spring Bean 快取

asdasdasd


擴充套件知識點—ObjectFactory 介面

這個介面通常用於封裝通用工廠,每次呼叫 getObject 方法的時候都會返回目標物件,這個物件可以是單例也可以是非單例的。

值得注意的是:這個介面雖然和 FactoryBean 類似,但後者的實現通常意味著定義為 BeanFactory 中的 SPI 例項,而此類的實現通常意味著作為 API 提供給其他 bean(通過注入)。 因此,getObject() 方法具有不同的異常處理行為。

這個介面在 Spring 中的預設實現:

  • RequestObjectFactory
  • ResponseObjectFactory
  • SessionObjectFactory
  • WebRequestObjectFactory
  • TargetBeanObjectFactory