电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

spring解決循環依賴的簡單方法

瀏覽:126日期:2023-08-13 16:19:27

Spring內部如何解決循環依賴,一定是單默認的單例Bean中,屬性互相引用的場景。比如幾個Bean之間的互相引用:

spring解決循環依賴的簡單方法

或者

spring解決循環依賴的簡單方法

setter方式原型,prototype

原型(Prototype)的場景是不支持循環依賴的,因為“prototype”作用域的Bean,為每一個bean請求提供一個實例,Spring容器不進行緩存,因此無法提前暴露一個創建中的Bean,會拋出異常。

構造器參數循環依賴

Spring容器會將每一個正在創建的Bean 標識符放在一個“當前創建Bean池”中,Bean標識符在創建過程中將一直保持在這個池中。

因此如果在創建Bean過程中發現自己已經在“當前創建Bean池”里時將拋出BeanCurrentlyInCreationException異常表示循環依賴;而對于創建完畢的Bean將從“當前創建Bean池”中清除掉。

Spring容器先創建單例A,A依賴B,然后將A放在“當前創建Bean池”中,此時創建B,B依賴C,然后將B放在“當前創建Bean池”中,此時創建C,C又依賴A, 但是,此時A已經在池中,所以會報錯,,因為在池中的Bean都是未初始化完的,所以會依賴錯誤 ,(初始化完的Bean會從池中移除)。

setter方式單例,默認方式

那么默認單例的屬性注入場景,Spring是如何支持循環依賴的?

既然,要解決循環依賴,那肯定存在著依賴,我們假設有兩個類:

A和B,A->B,B->A,且二者是通過@Autowired相互注入的。

我們假設從A開始創建,那就是先創建A對象,然后創建B對象,再通過反射把B對象set到A對象的屬性上去(fieldB.set(a, b)),在創建B的時候發現它又依賴于A,這時候同樣地,我要尋找一個A對象set到B的屬性上去,但是我們的系統中只能存在一個A對象(單例)。

為了解決這個問題,需要再前面創建A對象的時候就把它保存起來?我們假設保存在緩存中,后面B對象要使用的時候先去緩存中查找一下不就OK了嘛?!

所以,解決循環依賴的方法就是保存所有創建的對象,后面創建對象的時候有依賴的情況先去緩存中找一下,找到了直接set到那個正在創建的對象的屬性上,沒找到就創建一個新的對象給那個正在創建的對象,并保存到緩存中。

實際上,Spring中也是這么干的,只不過它的緩存不只一個,而是有四個。

具體可以看下這邊文章。

https://www.jb51.net/article/195897.htm

Spring解決循環依賴

首先,Spring內部維護了三個Map,也就是我們通常說的三級緩存。

在Spring的DefaultSingletonBeanRegistry類中,類上方掛著這三個Map:

singletonObjects 它是我們最熟悉的朋友,俗稱“單例池”“容器”,緩存創建完成單例Bean的地方。 singletonFactories 映射創建Bean的原始工廠 earlySingletonObjects 映射Bean的早期引用,也就是說在這個Map里的Bean不是完整的,甚至還不能稱之為“Bean”,只是一個Instance.

后兩個Map其實是“墊腳石”級別的,只是創建Bean的時候,用來借助了一下,創建完成就清掉了。

為什么成為后兩個Map為墊腳石,假設最終放在singletonObjects的Bean是你想要的一杯“涼白開”。

那么Spring準備了兩個杯子,即singletonFactories和earlySingletonObjects來回“倒騰”幾番,把熱水晾成“涼白開”放到singletonObjects中

循環依賴的本質

定義兩個類A與B:

public class A { private B b; public B getB() { return b; } public void setB(B b) { this.b = b; }}

public class B { public A getA() { return a; } public void setA(A a) { this.a = a; } private A a;}

public class CircularDependency { private static Map<String, Object> cacheMap = new HashMap<>(2); public static void main(String[] args) throws Exception { // 假裝掃描出來的對象 Class[] classes = { A.class, B.class }; // 假裝項目初始化實例化所有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)); } private static <T> T getBean(Class<T> beanClass) throws Exception{ // 本文用類名小寫 簡單代替bean的命名規則 String beanName = beanClass.getSimpleName().toLowerCase(); // 如果已經是一個bean,則直接返回 if (cacheMap.containsKey(beanName)) { return (T) cacheMap.get(beanName); } // 將對象本身實例化 Object object = beanClass.getDeclaredConstructor().newInstance(); // 放入緩存 cacheMap.put(beanName, object); // 把所有字段當成需要注入的bean,創建并注入到當前bean中 Field[] fields = object.getClass().getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); // 獲取需要注入字段的class Class<?> fieldClass = field.getType(); String fieldBeanName = fieldClass.getSimpleName().toLowerCase(); // 如果需要注入的bean,已經在緩存Map中,那么把緩存Map中的值注入到該field即可 // 如果緩存沒有 繼續創建 field.set(object, cacheMap.containsKey(fieldBeanName) ? cacheMap.get(fieldBeanName) : getBean(fieldClass)); } // 屬性填充完成,返回 return (T) object; }}

這段代碼的效果,其實就是處理了循環依賴,并且處理完成后,cacheMap中放的就是完整的“Bean”了。

總結

到此這篇關于spring解決循環依賴的文章就介紹到這了,更多相關spring解決循環依賴內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Spring
相關文章:
主站蜘蛛池模板: 浙江工业冷却塔-菱电冷却塔厂家 - 浙江菱电冷却设备有限公司 | YJLV22铝芯铠装电缆-MYPTJ矿用高压橡套电缆-天津市电缆总厂 | 郑州巴特熔体泵有限公司专业的熔体泵,熔体齿轮泵与换网器生产厂家 | 电杆荷载挠度测试仪-电杆荷载位移-管桩测试仪-北京绿野创能机电设备有限公司 | 【甲方装饰】合肥工装公司-合肥装修设计公司,专业从事安徽办公室、店面、售楼部、餐饮店、厂房装修设计服务 | 缝纫客| 手持式浮游菌采样器-全排二级生物安全柜-浙江孚夏医疗科技有限公司 | 写方案网_方案策划方案模板下载 事迹材料_个人事迹名人励志故事 | 减速机电机一体机_带电机减速器一套_德国BOSERL电动机与减速箱生产厂家 | 创绿家招商加盟网-除甲醛加盟-甲醛治理加盟-室内除甲醛加盟-创绿家招商官网 | 波纹补偿器_不锈钢波纹补偿器_巩义市润达管道设备制造有限公司 | 刺绳_刀片刺网_刺丝滚笼_不锈钢刺绳生产厂家_安平县浩荣金属丝网制品有限公司-安平县浩荣金属丝网制品有限公司 | 金环宇|金环宇电线|金环宇电缆|金环宇电线电缆|深圳市金环宇电线电缆有限公司|金环宇电缆集团 | 彭世修脚_修脚加盟_彭世修脚加盟_彭世足疗加盟_足疗加盟连锁_彭世修脚技术培训_彭世足疗 | 电子巡更系统-巡检管理系统-智能巡检【金万码】 | 电主轴-高速精密电主轴-高速电机厂家-瑞德沃斯品牌有限公司 | 苏州同创电子有限公司 - 四探针测试仪源头厂家 | 礼堂椅厂家|佛山市艺典家具有限公司 | 自动钻孔机-全自动数控钻孔机生产厂家-多米(广东)智能装备有限公司 | 北京网站建设公司_北京网站制作公司_北京网站设计公司-北京爱品特网站建站公司 | 耐火浇注料价格-高强高铝-刚玉碳化硅耐磨浇注料厂家【直销】 | MTK核心板|MTK开发板|MTK模块|4G核心板|4G模块|5G核心板|5G模块|安卓核心板|安卓模块|高通核心板-深圳市新移科技有限公司 | 智能型高压核相仪-自动开口闪点测试仪-QJ41A电雷管测试仪|上海妙定 | 12cr1mov无缝钢管切割-15crmog无缝钢管切割-40cr无缝钢管切割-42crmo无缝钢管切割-Q345B无缝钢管切割-45#无缝钢管切割 - 聊城宽达钢管有限公司 | 耐火浇注料价格-高强高铝-刚玉碳化硅耐磨浇注料厂家【直销】 | 优秀的临床医学知识库,临床知识库,医疗知识库,满足电子病历四级要求,免费试用 | 中矗模型-深圳中矗模型设计有限公司| 德州网站开发定制-小程序开发制作-APP软件开发-「两山开发」 | 飞利浦LED体育场灯具-吸顶式油站灯-飞利浦LED罩棚灯-佛山嘉耀照明有限公司 | 广西教师资格网-广西教师资格证考试网 | 仿古瓦,仿古金属瓦,铝瓦,铜瓦,铝合金瓦-西安东申景观艺术工程有限公司 | 网站建设,北京网站建设,北京网站建设公司,网站系统开发,北京网站制作公司,响应式网站,做网站公司,海淀做网站,朝阳做网站,昌平做网站,建站公司 | 长春网站建设,五合一网站设计制作,免费优化推广-长春网站建设 | 路面机械厂家| 水稻烘干机,小麦烘干机,大豆烘干机,玉米烘干机,粮食烘干机_巩义市锦华粮食烘干机械制造有限公司 水环真空泵厂家,2bv真空泵,2be真空泵-淄博真空设备厂 | 客服外包专业服务商_客服外包中心_网萌科技 | 北京律师事务所_房屋拆迁律师_24小时免费法律咨询_云合专业律师网 | 首页 - 军军小站|张军博客| 山东成考网-山东成人高考网 | 济南铝方通-济南铝方通价格-济南方通厂家-山东鲁方通建材有限公司 | 钢格板|镀锌钢格板|热镀锌钢格板|格栅板|钢格板|钢格栅板|热浸锌钢格板|平台钢格板|镀锌钢格栅板|热镀锌钢格栅板|平台钢格栅板|不锈钢钢格栅板 - 专业钢格板厂家 |