spring循環依賴

spring循環依賴有兩種狀況:spring

1.構造器循環依賴緩存

構造器循環依賴是沒辦法姐解決的,只能拋出BeanCurrentlyCreationException.prototype

由於spring在建立bean的時候,發現建立的bean依賴其餘bean,這時候spring會將該bean放入一個緩衝池(正在建立的緩衝池),而後再去建立其依賴的bean(每次建立bean的時候都會去校驗這個bean時是否在緩衝池中),直到最後一個依賴bean成功建立,沒成功建立一個bean,就會從緩衝池中刪除這個bean的狀態作用域

例如:io

A 依賴 B,B依賴C ,C依賴A,那麼在建立A的時候,發現A依賴B,那麼spring會把A打上一個標記(正在建立)放進緩衝池,轉而去建立B,發現B又依賴C,一樣會把B打上一個標記,轉而去建立C,在建立C的時候,發現C依賴A,則去建立A,這時候在建立A的時候發現A已經在緩衝池中了,表示這時候出現了循環依賴,就拋出異常依賴注入

2.setter循環依賴循環

對於setter循環依賴,spring只能解決單例做用域bean的setter循環依賴,能夠經過setAllowCircularReferences(false)來禁用循環引用。map

例如 A setter依賴B ,B setter依賴C, Csetter依賴A引用

1.在構造A的時候,先使用A默認的構造器初始化A,並暴露一個關於A的ObjectFactory放到SinglonFactory的map中緩存起來,而後setter注入B,這時候發現B尚未初始化,會把A打上一個正在建立的標記,並緩存起來,轉而去初始化B異常

2.初始化B的過程跟A同樣,會暴露一個ObjectFactory到singLonFactory緩存起來,

3.接着初始化C,一樣也會暴露一個ObjectFactory到singLonFactory緩存起來,這時候在setterA的時候,發如今singLonFactory中有關於A的ObjectFactory,那麼就能夠經過ObjectFactory提早暴露一個正在建立的A,這樣就完成了C的註冊,並刪除正在建立緩存吃中C的狀態

3.prototype做用域的bean沒法完成依賴注入,由於spring在建立prototype做用域的bean的時候,是不會緩存其正在建立的狀態,所以沒辦法提早暴露一個正在建立的bean

因此prototype做用域的bean出現循環依賴,則會拋BeanCurrentlyCreationException異常

相關文章
相關標籤/搜索