javascript
map 循环_被问到Spring循环依赖怎么解决?秀给面试官看!内附图解
不知道最近有沒有被一道Java面試題刷爆朋友圈,Spring框架的循環依賴如何解決。我收到了不少粉絲的提問,在了解到之后,也去網上查詢了一些資料,自己也詢問了身邊的同事,總結出以下幾個方面,今天就和我來看一看吧~
尋常情況下,如果問Spring內部怎么去解決循環的依賴性,一定是單默認的單例Bean中,屬性互相引用的場景。假設幾個Bean之間的互相引用,甚至循環依賴自己。
根據上面的兩個圖,我們先說一下循環依賴與原型的場景是不互相支持的,通常會走到AbstractBeanFactory類中下面的判斷,然后反饋回異常問題。
if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); }原因其實并不難,如果要創建一個新的A就會發現需要注入原型字段B,當創建新的原型字段B時又發現需要新的A。這就很尷尬了,禁止套娃!總不能靠猜去判斷先是StackOverflow還是OutOfMemory?這也太難了吧~
所以Spring怕你猜起來困難,就非常貼心的出現了BeanCurrentlyInCreationException。真不愧是我最愛的框架。
在基于在構造器上的循環依賴,這就不必再多說了,官方文檔有很明顯的指示,想讓構造器注入去支持循環依賴?這就不可能了,改代碼吧······
那么默認單例的屬性注入場景,那么Spring對循環依賴是如何支持的呢?
Spring解決循環依賴
這時候我們就不得不說到Spring的內部了,它內部維護了三個Map,這是什么?就是我們常說的三個緩存級別。這是為了讓更好理解,其實并沒有官方名字坐實這個三級緩存的概念。不過這不重要,接著看就是了。
在Spring的DefaultSingletonBeanRegistry類中,你就會發現它的上面有三個Map:
1.singletonObjects。這個或許是我們最熟悉的部分了,我們通常叫它:單例池,容器,它其實就是緩存創建完成單例Bean的地方。
2.singletonFactories。用來映射創建Bean的原始工廠。
3.earlySingletonObjects。它用來映射Bean的早期引用,這意思就是Map里的Bean并不完整,與其稱之為Bean,倒不說它只是一個Instance.
再往后的兩個Map就更像是一個“墊腳石”了,創建Bean時用了一下,用完就清理了。
循環依賴的本質
了解本質之后才能知道如何解決,剛才說了Spring如何處理循環依賴,首先,我們跳出“閱讀源碼”的思維,舉個例子,如果讓你實現下面的功能,你會如何去做?
1.將指定的一些類實例為單例
2.類中的字段同樣實例為單例
3.必須支持循環依賴
假設類A是存在的,那么
public class A { private B b; } // 類B: public class B { private A a; }看到了嗎?其實就是讓你模仿一下Spring,假設A和B被修飾,而且類之間的字段假設是通過Autowired修飾,然后放到Map里面,經過處理之后再放到Map里面。
其實上述并不是“Spring如何去解決循環依賴”而是循環依賴的基本本質,其實在網上可以搜索到很多例子,完全可以去百度一下看一看,這可以讓你不在閱讀的泥潭里陷得太深進而忽略了問題本質,如果實在是看不懂,逆推Spring的實現原因效果會好很多。
問題的本質竟然在于two sum?
說到這里有沒有覺得似曾相識?好像在什么時候見過似的,沒錯,和two sum的解題是很相似的。什么?你不知道two sum?two sum是刷題網站leetcode序號為1的題,也就是大多人的算法入門的第一題。經常有梗對于這個two sum,感興趣的可以去看看。咳咳,跑題了,我們再回來
問題的內容是:先給你規定數組,再給定一個數字。再返回到數組里面允許通過相加得到指定數字的兩個索引。我們舉個例子,給定nums = [2, 7, 11, 15], target = 9 那么要返回 [0, 1],因為2 + 7 = 9這道題的優解是,一次遍歷+HashMap:
class Solution { public int[] twoSum(int[] nums, int target) { Map<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < nums.length; i++) { int complement = target - nums[i]; if (map.containsKey(complement)) { return new int[] { map.get(complement), i }; } map.put(nums[i], i); } throw new IllegalArgumentException("No two sum solution"); } }這個時候就需要先去Map中尋找我們需要的數字,如果沒有,那么就將數字先保存到Map里面,再尋找到需要的數字時,一起返回即可。
總結
以上是生活随笔為你收集整理的map 循环_被问到Spring循环依赖怎么解决?秀给面试官看!内附图解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: wxpython图形编程_wxpytho
- 下一篇: 项目管理最佳实践方法_项目管理:控制项目