天天看點

【08】Spring源碼-分析篇-Bean的執行個體化

【08】Spring源碼-分析篇-Bean的執行個體化

Spring源碼-Bean的執行個體化

  接下來我們看看Bean的執行個體化處理

一、BeanDefinition

  首先我們來看看BeanDefinition的存放位置。因為Bean對象的執行個體化肯定是BeanFactory基于對應的BeanDefinition的定義來實作的,是以在這個過程中BeanDefinition是非常重要的,前面的課程講解已經完成了BeanDefinition的定義。同時根據前面refresh方法的講解我們知道了BeanFactory的具體實作是 ​

​DefaultListableBeanFactory​

​​.是以BeanDefinition的相關資訊是存儲在 ​

​DefaultListableBeanFactory​

​的相關屬性中的。

/** Map of bean definition objects, keyed by bean name. */
private final Map<String, BeanDefinition> beanDefinitionMap = new
ConcurrentHashMap<>(256);      

二、Bean執行個體的建立過程

  然後就是Bean執行個體的建立過程。這塊兒我們可以通過Debug的形式非常直覺的看到。

【08】Spring源碼-分析篇-Bean的執行個體化

  按照這種步驟一個個去分析就OK了。

三、單例對象

  在建立單例對象的時候是如何儲存單例的特性的?這塊我們需要注意下面的代碼

【08】Spring源碼-分析篇-Bean的執行個體化

然後進入到getSingleton方法中。

【08】Spring源碼-分析篇-Bean的執行個體化

建立成功的單例對象會被緩存起來。在 addSingleton 方法中

【08】Spring源碼-分析篇-Bean的執行個體化
【08】Spring源碼-分析篇-Bean的執行個體化

是以singletonObjects是緩存所有Bean執行個體的容器

【08】Spring源碼-分析篇-Bean的執行個體化

而具體建立單例Bean的邏輯會回調前面的Lambda表達式中的createBean方法

【08】Spring源碼-分析篇-Bean的執行個體化
【08】Spring源碼-分析篇-Bean的執行個體化

四、單例對象的銷毀

  然後我們先來看下一個單例Bean對象的銷毀過程。定義一個案例

【08】Spring源碼-分析篇-Bean的執行個體化

然後我們在測試的案例中顯示的調用 ​

​close​

​方法

【08】Spring源碼-分析篇-Bean的執行個體化

執行的時候可以看到相關的日志執行了。

【08】Spring源碼-分析篇-Bean的執行個體化

進入到close方法中分析,比較核心的有兩個位置。在doClose方法中。

【08】Spring源碼-分析篇-Bean的執行個體化

具體銷毀的代碼進入destroyBeans()中檢視即可。

在doClose方法中有個提示。registerShutdownHook方法

【08】Spring源碼-分析篇-Bean的執行個體化
@Override
  public void registerShutdownHook() {
    if (this.shutdownHook == null) {
      // No shutdown hook registered yet.
      this.shutdownHook = new Thread(SHUTDOWN_HOOK_THREAD_NAME) {
        @Override
        public void run() {
          synchronized (startupShutdownMonitor) {
            doClose();
          }
        }
      };
      Runtime.getRuntime().addShutdownHook(this.shutdownHook);
    }
  }      

對應的在web項目中就有對應的調用