在 Spring 框架里,循環依賴指的是多個 Bean 之間相互依賴,從而形成一個閉環。例如,Bean A 依賴 Bean B,而 Bean B 又依賴 Bean A。Spring 主要通過三級緩存機制來處理循環依賴,下面詳細介紹相關內容。
1. 三級緩存的定義
- 一級緩存(singletonObjects):這是一個 Map,用于存放已經完全初始化好的單例 Bean,這些 Bean 可以直接使用。
- 二級緩存(singletonFactories):同樣是一個 Map,用于存放提前暴露的單例 Bean 工廠,這里的 Bean 處于創建過程中,還未完成初始化。
- 三級緩存(earlySingletonObjects):也是一個 Map,用于存放提前暴露的單例 Bean,這些 Bean 只是實例化了,但未完成屬性注入和初始化操作。
2. 處理循環依賴的過程
- 創建 Bean A:當需要創建 Bean A 時,Spring 會先將 Bean A 的創建工廠放入三級緩存 singletonFactories 中,然后開始進行 Bean A 的實例化操作。
- 屬性注入:在對 Bean A 進行屬性注入時,發現它依賴于 Bean B,于是 Spring 開始創建 Bean B。
- 創建 Bean B:如同創建 Bean A 一樣,Spring 先把 Bean B 的創建工廠放入三級緩存 singletonFactories 中,接著實例化 Bean B。
- 屬性注入:在對 Bean B 進行屬性注入時,發現它依賴于 Bean A。此時,Spring 會從三級緩存 singletonFactories 中獲取 Bean A 的創建工廠,通過該工廠提前獲取到 Bean A 的早期引用,并將其放入二級緩存 earlySingletonObjects 中,同時從三級緩存 singletonFactories 中移除 Bean A 的創建工廠。
- 完成 Bean B 的創建:將從二級緩存 earlySingletonObjects 中獲取到的 Bean A 的早期引用注入到 Bean B 中,然后完成 Bean B 的屬性注入和初始化操作,最后將 Bean B 放入一級緩存 singletonObjects 中。
- 完成 Bean A 的創建:由于 Bean B 已經創建完成,將其注入到 Bean A 中,接著完成 Bean A 的屬性注入和初始化操作,最終把 Bean A 放入一級緩存 singletonObjects 中。