1. 程式人生 > >Spring裡面Bean的生命週期和迴圈依賴問題

Spring裡面Bean的生命週期和迴圈依賴問題

1. 什麼是Spring的迴圈依賴?

     迴圈依賴不是我們程式裡面的死迴圈,它是一種物件之間的依賴關係。

2. Spring如何檢測迴圈依賴?

    Spring在建立Bean的時候做一個標記,採用遞迴進行呼叫如果發現Bean還在建立中,就說明有迴圈依賴。

3. Spring迴圈依賴產生的時機?

    我們知道Spring注入的方式有三種 ,分別是構造方法,屬性注入,自動注入,構造方法和屬性注入是比較常用的。

    現在這樣一個場景,A---》B-- >C ---》A,A依賴B,B依賴C,C依賴A,如果使用構造方法,將會產生錯誤,錯誤資訊是正在製作的Bean。

   但是使用屬性注入的方式,將不會產生錯誤,這是因為Spring採用構造方法先例項化Bean,然後把它放到對應CurrentHashMap中,但是沒有設定屬性值。也就是說我們可以得到未設定屬性的bean,及可以得到例項化BeanA,但是A依賴B,這樣就可以從map裡面取出B的例項,這樣就可以迴圈依賴問題。

4. 如何解決Spring迴圈依賴?

      那麼需要在spring原始碼裡面的看createBean() --- 》doCreateBean()方法

     分析:我們得到一個完整例項bean,需要通過上面三個步驟:

             1.  createBeanInstance方法: 得到一個例項bean,但是沒有進行屬性值的注入

             2.  populateBean方法:就是對bean進行屬性值注入。

             3.  initializeBean方法:如果配置檔案裡面有init方法,需要執行init方法。

           可以看出第一步和第二部比較重要,這裡面就是解決bean依賴的關鍵

     分析:我們可以看出進行createBeanInstance方法,得到了bean例項物件,但是沒有屬性注入。把沒有完全例項化的bean,放到addSinletonFactory方法裡面去,這樣相當於就是提前暴露bean,接下來addSinletonFactory方法,這裡面使用三個Map型別的,及三級快取來解決迴圈依賴。接下我們看一下addSingletonFactory方法實現。

分析:這三個Map型別是什麼呢?

         singleObjects--》單例物件的cache:一級快取

          earlySingletonObjects --》提前暴光的單例物件的Cache :二級快取

         singletonFactories --》單例物件工廠的cache :三級快取

分析:這就是得到一個未完全例項化的bean,以及得到它的過程。