<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      技術(shù)面:Spring(循環(huán)依賴,spring與springboot的區(qū)別)

      Spring的循環(huán)依賴

      循環(huán)依賴是指在使用Spring框架的過程中,兩個(gè)或多個(gè)Bean之間在初始化的過程相互依賴,形成一個(gè)依賴閉環(huán),導(dǎo)致容器無法順利完成Bean的創(chuàng)建和注入,從而可能引發(fā)啟動(dòng)失敗或運(yùn)行異常。

      @Service
      public class ServiceA {
          @Autowired
          private ServiceB serviceB;
      }
      
      @Service
      public class ServiceB {
          @Autowired
          private ServiceA serviceA;
      }
      

      在上面這段代碼中:
      ServiceA 的實(shí)例需要注入 ServiceB 的實(shí)例。
      ServiceB 的實(shí)例又需要注入 ServiceA 的實(shí)例。
      這就形成了一個(gè) ServiceA → ServiceB → ServiceA 的循環(huán)依賴。
      當(dāng)然大于兩個(gè)的類也可能存在循環(huán)依賴,例如:A→ B→ C→ A
      image
      image

      如何解決循環(huán)依賴

      在Spring中解決循環(huán)依賴也是有一定限制的。

      1. 循環(huán)依賴的Bean都是單例模式的Bean。
      2. 依賴注入的方式不能都是構(gòu)造函數(shù)注入的方式。

      Spring解決循環(huán)依賴為什么只支持單例模式的Bean

      從本質(zhì)上來說Spring解決循環(huán)依賴的方式是通過提前暴露未初始化完成的Bean來解決循環(huán)依賴的,這個(gè)尚未初始化完成的Bean是個(gè)半成品的Bean,就是未了解決循環(huán)依賴才提前放到緩存中的。

      在Spring容器中,單例Bean的創(chuàng)建和初始化只會(huì)發(fā)生一次,而且是在容器啟動(dòng)的時(shí)候就完成的。這就說明在整個(gè)容器運(yùn)行期間,單例Bean的依賴關(guān)系不會(huì)再發(fā)生變化,因此可以在容器啟動(dòng)的時(shí)候,通過提前暴露半成品的Bean來一次性解決單例Bean循環(huán)依賴的問題。
      image
      而由于原型模式(property)的Bean或Session模型下的Bean,創(chuàng)建和初始化會(huì)發(fā)生多次,并且是在Spring容器運(yùn)行期間動(dòng)態(tài)的發(fā)生變化,因此提前暴露半成品的Bean并不能解決循環(huán)依賴的問題,因?yàn)樵诤罄m(xù)的創(chuàng)建過程中,可能會(huì)涉及到多個(gè)不同的原型Bean,這就無法像單例Bean那樣緩存并復(fù)用半成品對象。

      所以Spring只能自動(dòng)解決單例Bean的循環(huán)依賴。

      Spring為什么不支持自動(dòng)解決構(gòu)造函數(shù)的循環(huán)依賴

      這個(gè)也很好理解,因?yàn)樵谡麄€(gè)Bean的實(shí)例化的過程中,是先執(zhí)行構(gòu)造函數(shù),只有執(zhí)行了構(gòu)造函數(shù)后,才算是在堆內(nèi)存中分配了內(nèi)存,后面再填充屬性,內(nèi)存地址也不會(huì)有變化了。但是如果連構(gòu)造函數(shù)都執(zhí)行不成功,那這個(gè)Bean就連個(gè)半成品都不算,所以spring無法解決這種循環(huán)依賴。
      image
      解決這種構(gòu)造函數(shù)的循環(huán)依賴有多種方式

      • 重新設(shè)計(jì),從代碼層面就把循環(huán)依賴給杜絕掉,徹底避免循環(huán)依賴。
      • 改成非構(gòu)造函數(shù)依賴,可以采用setter注入或?qū)傩宰⑷?/li>
      • 使用@Lazy注解解決:使用@Lazy注解時(shí),Spring容器會(huì)在實(shí)際需要該Bean的時(shí)候才會(huì)進(jìn)行實(shí)例化,而不是在容器啟動(dòng)的時(shí)候進(jìn)行實(shí)例化。這樣如果兩個(gè)Bean存在循環(huán)依賴,可以使用這種延遲實(shí)例化,從而避免在容器啟動(dòng)時(shí)觸發(fā)循環(huán)依賴,但并未真正解決循環(huán)依賴本身。

      Spring三級緩存

      Spring三級緩存是什么?

      在Spring框架中,BeanFactory是IOC的基礎(chǔ)接口,其中DefaultSingletonBeanRegistry類實(shí)現(xiàn)了BeanFactory接口,并維護(hù)了三個(gè)Map,用來做Bean創(chuàng)建時(shí)的三級緩存。
      image
      這三級緩存的介紹

      1. 一級緩存,singletonObjects 單例緩存
        • 類型:ConcurrentHashMap<String, Object>
        • 作用:存放完全初始化完成的單例Bean實(shí)例。
        • 說明:這是最終的單例池,所有已經(jīng)創(chuàng)建并裝配好的Bean都會(huì)放在這里,供后續(xù)直接獲取使用。
      2. 二級緩存:earlySingletonObjects
        • 類型:ConcurrentHashMap<String, Object>
        • 作用:存放早期暴露的Bean實(shí)例(原始對象,尚未完成屬性注入和初始化,半成品)。
        • 當(dāng)一個(gè)Bean正在創(chuàng)建中,但還未完成所有初始化步驟時(shí),可以提前暴露一個(gè)“半成品”對象,放入此緩存,供其他Bean引用,從而打破循環(huán)依賴。
      3. 三級緩存:singletonFactories
        • 類型:ConcurrentHashMap<String, ObjectFactory<?>>
        • 作用:存放能夠創(chuàng)建早期Bean實(shí)例的工廠對象(ObjectFactory)。
        • 它并不直接存儲(chǔ)Bean實(shí)例,而是存儲(chǔ)一個(gè)lambda或匿名內(nèi)部類,用于在需要時(shí)生成早期暴露的對象。這允許Spring在暴露早期對象的同時(shí),還能應(yīng)用一些后置處理器(如AOP代理)。

      Spring三級緩存是怎么解決循環(huán)依賴的?

      步驟一:創(chuàng)建Bean-A
      • Spring 啟動(dòng)創(chuàng)建 Bean-A 的流程。在實(shí)例化(instantiateBean)之后,屬性注入(populateBean)之前,Spring 會(huì)將一個(gè) ObjectFactory(工廠)放入 三級緩存 (singletonFactories)。
      • 這個(gè) ObjectFactory 的作用是:當(dāng)被調(diào)用時(shí),可以返回 Bean-A 的一個(gè)早期引用(通常是原始對象,或者如果需要AOP,則是一個(gè)代理對象)。
      步驟二:創(chuàng)建 Bean-A 的依賴 (Bean-B)
      • Spring 開始為 Bean-A 注入屬性,發(fā)現(xiàn)需要 Bean-B。
      • 檢查一級緩存 (singletonObjects),沒有找到 Bean-B。
      • 檢查二級緩存 (earlySingletonObjects),也沒有。
      • 檢查三級緩存 (singletonFactories),同樣沒有 Bean-B。

      因此,Spring 開始創(chuàng)建 Bean-B。

      步驟三:開始創(chuàng)建 Bean-B
      • Bean-B 被實(shí)例化。
      • 同樣地,Spring 將一個(gè)用于創(chuàng)建 Bean-B 早期引用的 ObjectFactory 放入 三級緩存。
      步驟四:創(chuàng)建 Bean-B 的依賴 (Bean-A)
      • Spring 開始為 Bean-B 注入屬性,發(fā)現(xiàn)需要 Bean-A。
      • 檢查一級緩存,沒有完整的 Bean-A。檢查二級緩存,沒有。
      • 檢查三級緩存,發(fā)現(xiàn)存在 Bean-A 的 ObjectFactory!
      • Spring 調(diào)用這個(gè) ObjectFactory.getObject() 方法。
      • ObjectFactory 執(zhí)行其邏輯(通常會(huì)調(diào)用 getEarlyBeanReference()),返回 Bean-A 的一個(gè)早期引用。
      • 這個(gè)早期引用被放入 二級緩存 (earlySingletonObjects),同時(shí)從三級緩存中移除對應(yīng)的工廠。
      • Spring 將這個(gè)早期引用的 Bean-A 注入到 Bean-B 中。
      步驟五:完成 Bean-B 的創(chuàng)建
      • Bean-B 完成屬性注入和初始化。
      • 完全初始化好的 Bean-B 被放入 一級緩存 (singletonObjects)。
      • 從二級緩存中移除 Bean-B 的早期引用。
      步驟六:回到 Bean-A 的創(chuàng)建
      • 現(xiàn)在 Bean-B 已經(jīng)創(chuàng)建完畢并放入一級緩存。
      • Spring 繼續(xù)為 Bean-A 注入屬性,需要 Bean-B。
      • 直接從 一級緩存 中獲取到完整的 Bean-B,注入到 Bean-A 中。
      • Bean-A 完成后續(xù)的初始化流程。
      • 完全初始化好的 Bean-A 被放入 一級緩存 (singletonObjects)。
      • 此時(shí),Bean-A 和 Bean-B 都已創(chuàng)建完畢,循環(huán)依賴成功解決。

      解決循環(huán)依賴一定要三級緩存嗎?

      其實(shí)理論上,一級加二級緩存就可以解決簡單場景的單例Bean的循環(huán)依賴,但是三級緩存的設(shè)計(jì)還涉及到更豐富場景的支持,例如:支持AOP(動(dòng)態(tài)代理)的代理對象的提前暴露。

      如果只有二級緩存:在 Bean-A 實(shí)例化后,直接將其原始對象放入二級緩存。當(dāng) Bean-B 需要時(shí),直接從二級緩存拿到原始的 Bean-A。

      如果 Bean-A 需要被 AOP 代理(例如添加事務(wù)),那么最終放入一級緩存的應(yīng)該是 代理對象,而不是原始對象。

      但如果二級緩存里已經(jīng)存了原始對象,那么 Bean-B 拿到的就是原始對象,這就導(dǎo)致了 不一致性:Bean-B 持有的是原始對象,而其他地方(一級緩存)持有的是代理對象

      即便沒有 AOP,三級緩存的設(shè)計(jì)也有其必要性。它通過 ObjectFactory 延遲暴露早期引用,確保 Spring 可以在需要時(shí)介入生成代理或執(zhí)行后置處理器,而不僅僅是直接返回原始對象。

      Spring默認(rèn)支持循環(huán)依賴嗎

      這個(gè)是看具體版本而言的,在SpringBoot2.6之前是默認(rèn)支持循環(huán)依賴的,但是從Spring Boot 仍支持循環(huán)依賴,但變?yōu)榭膳渲庙?xiàng),且默認(rèn)關(guān)閉,也就是說從SpringBoot2.6以后是默認(rèn)不支持循環(huán)依賴的,如果啟動(dòng)時(shí)存在循環(huán)依賴,這個(gè)配置未打開,是會(huì)報(bào)錯(cuò)的。

      雖然默認(rèn)不再支持循環(huán)依賴,但是我們可以通過以下方式開啟對循環(huán)依賴的支持。

      1. 在配置文件中加入此配置spring.main.allow-circular-references=true
      2. @Lazy注解,在@Autoired地方增加即可。

      Spring 團(tuán)隊(duì)已明確表示 未來可能徹底移除循環(huán)依賴支持,建議開發(fā)者避免依賴此機(jī)制

      Spring和SpringBoot的區(qū)別

      Spring 和 SpringBoot 是 Java 生態(tài)中非常重要的兩個(gè)框架,它們密切相關(guān),但定位和目標(biāo)不同。
      簡單來說,Spring 是一個(gè)功能強(qiáng)大的基礎(chǔ)框架,而 SpringBoot 是建立在 Spring 之上的“腳手架”工具,旨在簡化 Spring 應(yīng)用的開發(fā)和部署。

      以下幾點(diǎn)是SpringBoot在Spring的基礎(chǔ)上做的最主要的幾點(diǎn)來提升開發(fā)效率與降低開發(fā)成本:

      1. 自動(dòng)配置,SpringBoot通過Auto-Configuration來減少開發(fā)人員的配置工作??梢酝ㄟ^引入一個(gè) starter 一次性引入所需的所有依賴,使開發(fā)人員可以更專注于業(yè)務(wù)邏輯而不是配置。
      2. 內(nèi)嵌Web服務(wù)器,SpringBoot內(nèi)置了常見的Web服務(wù)器(如Tomcat、Jetty),這意味著您可以輕松創(chuàng)建可運(yùn)行的獨(dú)立應(yīng)用程序,而無需外部Web服務(wù)器。
      3. 約定大于配置,SpringBoot中有很多約定大于配置的思想的體現(xiàn),通過一種約定的方式,來降低開發(fā)人員的配置工作。如他默認(rèn)讀取spring.factories來加載starter、讀取application.propertiesapplication.yml文件來進(jìn)行屬性配置等。

      更詳細(xì)的區(qū)別

      特性 Spring SpringBoot
      核心定位 一個(gè)全面的、基礎(chǔ)的 Java 框架,提供企業(yè)級應(yīng)用開發(fā)的核心功能(如依賴注入、面向切面編程) Spring 框架的擴(kuò)展,專注于簡化 Spring 應(yīng)用的開發(fā)和配置,實(shí)現(xiàn)"開箱即用"
      配置方式 需要大量手動(dòng)配置(XML 或 Java 配置類),例如:
      - 配置數(shù)據(jù)源
      - 配置 MVC 分發(fā)器
      - 配置事務(wù)管理
      通過自動(dòng)配置(Auto-Configuration)機(jī)制,根據(jù) classpath 中的依賴自動(dòng)配置應(yīng)用,只需少量配置(如 application.properties
      依賴管理 需要手動(dòng)管理所有 Spring 模塊(如 spring-core, spring-webmvc)和其他第三方庫的版本,容易出現(xiàn)版本沖突 通過起步依賴(Starter Dependencies)簡化依賴管理:
      - 例如 spring-boot-starter-web 自動(dòng)引入 Spring MVC、Tomcat 等所有必要依賴
      - Spring Boot 的父 POM 管理了所有依賴版本,確保兼容性
      內(nèi)嵌服務(wù)器 傳統(tǒng) Spring 應(yīng)用需要將應(yīng)用打包成 WAR 文件,部署到外部 Servlet 容器(如 Tomcat、Jetty) 內(nèi)置了 Tomcat、JettyUndertow 等 Web 服務(wù)器,應(yīng)用可打包成可執(zhí)行 JAR 文件,通過 java -jar 直接運(yùn)行
      開發(fā)效率 需要大量基礎(chǔ)配置工作,初始搭建速度較慢 極大提高開發(fā)效率,開發(fā)者可以專注于業(yè)務(wù)邏輯,無需關(guān)注基礎(chǔ)配置
      監(jiān)控與管理 需要自行集成健康檢查、指標(biāo)收集等功能 通過 Spring Boot Actuator 提供開箱即用的生產(chǎn)級監(jiān)控功能:
      - 健康檢查(health
      - 指標(biāo)收集(metrics
      - 外部化配置(configprops
      - 環(huán)境信息(env
      適用場景 適合需要高度定制化、復(fù)雜配置的大型企業(yè)級應(yīng)用 適合快速開發(fā)微服務(wù)、RESTful API、需要快速迭代的中小型項(xiàng)目,是構(gòu)建現(xiàn)代云原生應(yīng)用的首選
      posted @ 2025-10-22 09:38  紀(jì)莫  閱讀(216)  評論(3)    收藏  舉報(bào)
      主站蜘蛛池模板: 久热综合在线亚洲精品| 成人永久免费A∨一级在线播放| 国产丰满老熟女重口对白| 免费看国产精品3a黄的视频| 国产精品亚洲av三区色| 国产尤物精品自在拍视频首页 | 久久青青草原亚洲AV无码麻豆| 日韩亚洲精品中文字幕| 国产三级无码内射在线看| 国产嫩草精品网亚洲av| 高清破外女出血AV毛片| 国产一区二区精品久久凹凸| 无码中文字幕av免费放| 青草成人精品视频在线看| 亚洲AV高清一区二区三区尤物| 日韩丝袜亚洲国产欧美一区 | 好硬好湿好爽好深视频| 国产午夜福利不卡在线观看| 国产福利在线观看免费第一福利| 中国女人高潮hd| 久久夜色撩人国产综合av| 国内少妇偷人精品免费| 兖州市| 亚洲a片无码一区二区蜜桃| 深夜av免费在线观看| 无码人妻丰满熟妇区bbbbxxxx| 开心激情站一区二区三区| 无码日韩精品一区二区三区免费| 国产欧美一区二区精品仙草咪| 精品尤物国产尤物在线看| 国内不卡不区二区三区| 久久精品国产99国产精品澳门| 无码国内精品人妻少妇| 国产亚洲精品国产福APP| 在线a级毛片无码免费真人| 国产精品一区二区三区黄色| 国产-第1页-浮力影院| 国产精品一区二区久久岳| 国产精品亚洲А∨怡红院| 长腿校花无力呻吟娇喘| 免费看欧美日韩一区二区三区|