深入圖解 Spring 循環(huán)依賴
點(diǎn)擊“開發(fā)者技術(shù)前線”,選擇“星標(biāo)?”
讓一部分開發(fā)者看到未來
本文來源:
https://juejin.im/post/5e927e27f265da47c8012ed9
正文


if?(isPrototypeCurrentlyInCreation(beanName))?{
??throw?new?BeanCurrentlyInCreationException(beanName);
}

Spring解決循環(huán)依賴
singletonObjects 它是我們最熟悉的朋友,俗稱“單例池”“容器”,緩存創(chuàng)建完成單例Bean的地方。 singletonFactories 映射創(chuàng)建Bean的原始工廠 earlySingletonObjects 映射Bean的早期引用,也就是說在這個(gè)Map里的Bean不是完整的,甚至還不能稱之為“Bean”,只是一個(gè)Instance.

循環(huán)依賴的本質(zhì)
將指定的一些類實(shí)例為單例 類中的字段也都實(shí)例為單例 支持循環(huán)依賴
public?class?A?{
????private?B?b;
}
//?類B:
public?class?B?{
????private?A?a;
}
?/**
?????*?放置創(chuàng)建好的bean?Map
?????*/
????private?static?Map?cacheMap?=?new?HashMap<>(2);
????public?static?void?main(String[]?args)?{
????????//?假裝掃描出來的對(duì)象
????????Class[]?classes?=?{A.class,?B.class};
????????//?假裝項(xiàng)目初始化實(shí)例化所有bean
????????for?(Class?aClass?:?classes)?{
????????????getBean(aClass);
????????}
????????//?check
????????System.out.println(getBean(B.class).getA()?==?getBean(A.class));
????????System.out.println(getBean(A.class).getB()?==?getBean(B.class));
????}
????@SneakyThrows
????private?static??T?getBean(Class?beanClass) ?{
????????//?本文用類名小寫?簡單代替bean的命名規(guī)則
????????String?beanName?=?beanClass.getSimpleName().toLowerCase();
????????//?如果已經(jīng)是一個(gè)bean,則直接返回
????????if?(cacheMap.containsKey(beanName))?{
????????????return?(T)?cacheMap.get(beanName);
????????}
????????//?將對(duì)象本身實(shí)例化
????????Object?object?=?beanClass.getDeclaredConstructor().newInstance();
????????//?放入緩存
????????cacheMap.put(beanName,?object);
????????//?把所有字段當(dāng)成需要注入的bean,創(chuàng)建并注入到當(dāng)前bean中
????????Field[]?fields?=?object.getClass().getDeclaredFields();
????????for?(Field?field?:?fields)?{
????????????field.setAccessible(true);
????????????//?獲取需要注入字段的class
????????????Class>?fieldClass?=?field.getType();
????????????String?fieldBeanName?=?fieldClass.getSimpleName().toLowerCase();
????????????//?如果需要注入的bean,已經(jīng)在緩存Map中,那么把緩存Map中的值注入到該field即可
????????????//?如果緩存沒有?繼續(xù)創(chuàng)建
????????????field.set(object,?cacheMap.containsKey(fieldBeanName)
??????????????????????cacheMap.get(fieldBeanName)?:?getBean(fieldClass));
????????}
????????//?屬性填充完成,返回
????????return?(T)?object;
????}

what?問題的本質(zhì)居然是two sum!
class?Solution?{
????public?int[]?twoSum(int[]?nums,?int?target)?{
????????Map?map?=?new?HashMap<>();
????????for?(int?i?=?0;?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");
????}
}
結(jié)尾
? 最后給讀者整理了一份大廠面試真題,需要的可掃碼加我微信獲取。

前線推出學(xué)習(xí)交流群,加群一定要備注: 研究/工作方向+地點(diǎn)+學(xué)校/公司+昵稱(如前端+上海+上交+可可) 根據(jù)格式備注,可更快被通過且邀請(qǐng)進(jìn)群,領(lǐng)取一份專屬學(xué)習(xí)禮包
掃碼加我微信進(jìn)群,內(nèi)推和技術(shù)交流,大佬們零距離
歷史推薦
京東推出輕量級(jí)分布式 RPC 框架 — EasyRPC 2020 最好的 10 大學(xué)習(xí)編程網(wǎng)站! 刷題一個(gè)半月,一口氣拿下騰訊、華為、Oppo 、微軟7個(gè)大廠offer, 字節(jié)跳動(dòng)薪資漲幅60%! 騰訊視頻 Python 爬蟲項(xiàng)目實(shí)戰(zhàn) 好文點(diǎn)個(gè)在看吧!
評(píng)論
圖片
表情



