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

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

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

      技術面:SpringBoot(springboot的類加載和傳統的雙親委派有什么區別、如何按順序實例化Bean)

      前言

      SpringBoot中,類加載機制與Java的傳統雙親委派類加載機制是有一定區別。主要體現在自定義類加載器fat jar(可執行jar)的加載方式上。

      Java的傳統雙親委派模型

      Java傳統類加載機制,遵循雙親委派模型,核心規則:類加載請求優先由父類加載器處理,只有父加載器無法加載時才由子加載器嘗試。
      1、JDK 1.8及更早版本采用如下層級結構:
      image

      2、從 JDK 9 引入模塊系統開始,是這樣的層級結構
      image
      這樣設計的主要目的是為了,避免重復加載核心類(如java.lang.String),確保安全性(防止用戶篡改核心類)

      SpringBoot的類加載器改造

      改造原因

      SpringBoot通過自定義類加載器LaunchedURLClassLoader打破了傳統雙親委派的嚴格層級,主要解決fat jar中嵌套jar的加載問題。

      SpringBoot中,使用打包構建工具時,無論是Maven還是Gradle,在lib/目錄中的第三方依賴是以JAR形式打入項目主JAR內的,默認會生成一個包含所有依賴項的fat jar
      目錄結構示例如下:

      mySpringBootApp.jar
      ├── BOOT-INF
      │   ├── classes(用戶代碼)
      │   └── lib(依賴的第三方jar)
      └── org.springframework.boot.loader
      

      傳統的Java類加載機制,Application ClassLoader只能從外部classpath加載類,無法直接加載JAR包內嵌的其他JAR(fat jar),因此SpringBoot加入了自定義的類加載器。

      主要做了哪些改造

      SpringBoot使用LaunchedURLClassLoader(繼承自URLClassLoader)替代了ApplicationClassLoader,通過運行時動態生成jar路徑的URL來加載嵌套jar。

      • LaunchedURLClassLoader會先加載BOOT-INF/classes目錄下的應用類(優先于JDK類)。
      • 再加載BOOT-INF/lib/目錄下的依賴JAR,LaunchedURLClassLoader會解析BOOT-INF/lib/下的每個jar,將其URL添加到類路徑中。
      • 最后再交給父類加載器(即ApplicationClassLoader)。

      總結一下:為了加載嵌套在主JAR內部的fat jar,SpringBoot在類加載流程上做了改造,增加了LaunchedURLClassLoader類加載器,并且會先嘗試加載自身的類和依賴JAR,找不到要加載的類時,才交給父類加載器,從而對傳統的雙親委派模型進行了改造。

      注意,LaunchedURLClassLoader 僅對 BOOT-INF/classes 和 BOOT-INF/lib 下的類采用“子加載器優先”策略,核心類庫仍嚴格遵循雙親委派,因此不會破壞 JDK 的安全模型。

      擴展知識

      在使用SpringBoot進行開發項目時,SpringBoot官方推薦我們使用熱部署的方式是使用 spring-boot-devtools 模塊。

      其實SpringBoot的熱部署并不是真正意義上的“熱替換”,而是通過 雙類加載器機制 實現的“快速重啟”。

      SpringBoot的“熱部署”主要實現原理如下:

      1. 雙 ClassLoader 架構
        • Base ClassLoader:加載第三方 jar 包(不會頻繁變動)
        • Restart ClassLoader:加載開發者自己寫的類(會頻繁變動)
      2. 文件變化監聽機制
        • DevTools 啟動一個后臺線程,監聽 classpath.class 文件的變化
        • 一旦檢測到變化,丟棄舊的 Restart ClassLoader
        • 重新創建一個新的 Restart ClassLoader,加載更新后的類
        • 然后通過反射重新調用 main() 方法,實現應用重啟

      由于不需要重新加載第三方類(Base ClassLoader 不變),也不需要重新初始化整個 Spring 容器,重啟過程只涉及開發者代碼部分,節省大量時間。

      雖然叫“熱部署”,但本質上是“部分重啟”,不是真正的 JVM 熱替換(如 JRebel 那樣)

      SpringBoot如何指定在其他Bean之前實例化指定的Bean

      Bean 實例化/初始化順序其實就是指“哪個 Bean 先被 new、哪個 @PostConstruct 先跑”。

      目前有6種方式可以實現按照一定順序進行實例化Bean。

      1、構造器依賴(最穩,無侵入)

      Spring 保證一個 Bean 實例化之前,它依賴的 Bean 必須已實例化。
      直接讓 BeanA 的構造器里需要 BeanB,或者 BeanA 里有一個非延遲的 BeanB 字段 + @Autowired

      如下代碼

      @Configuration
      public class Config {
          @Bean
          public B b() { return new B(); }
      
          @Bean
          public A a(B b) {      // Spring 保證 b() 先跑
              return new A(b);
          }
      }
      

      使用這種方式,理解起來簡單,并且可靠性高,與具體的應用框架無關,但是也有一定的短板,就是按指定順序實例化的Bean,必須存在真實的依賴關系。

      2、@DependsOn(顯式聲明,無真正依賴也適用)

      雖然兩個 Bean 之間沒有構造器/字段依賴,但你仍想讓 BeanB 先實例化于BeanA。
      這個時候就可以使用@DependsOn注解了,但是需要注意一點:@DependsOn 只能保證先實例化,不能保證先銷毀(銷毀順序用 DependentBean.destroyMethodDisposableBeanAdapter)。

      @DependsOn 僅控制 初始化順序;銷毀時 Spring 會按依賴關系的反向順序執行,因此若 B 依賴 A,則 B 先銷毀,A 后銷毀。

      如下代碼:

      @Configuration
      public class Config {
          @Bean
          public B b() { return new B(); }
      
          @Bean
          @DependsOn("b")   // 容器會先實例化 b,再實例化 a
          public A a() { return new A(); }
      }
      

      直接將注解寫在類上也可以

      @Component
      @DependsOn("b")
      public class A { }
      

      3、@Order 或 Ordered(只影響“收集型”順序)

      適用范圍:

      • @Bean 方法返回的是 Collection 注入點(如 List<X>、Map<String,X>)。
      • CommandLineRunner / ApplicationRunner / Filter / Interceptor 等“鏈式”擴展點。對普通的單例 Bean 實例化順序無效。

      即使兩個單例 Bean 實現了 Ordered 接口,只要它們之間不存在“收集型注入”或“鏈式擴展點”,Spring 仍然不保證誰先實例化。

      使用場景如下代碼示例,使用此注解的Bean都是實現了同一個接口的同類型。

      @Component
      @Order(1)
      public class FirstRunner implements CommandLineRunner { ... }
      
      @Component
      @Order(2)
      public class SecondRunner implements CommandLineRunner { ... }
      

      4、BeanDefinitionRegistryPostProcessor(BeanFactoryPostProcessor 的擴展)

      在容器刷新早期(所有 BeanDefinition 加載完、實例化之前)把定義順序調到自己想要的順序。

      @Component
      public class OrderBeanProcessor implements BeanFactoryPostProcessor {
      
      		// 讓某個 Bean 在普通 Bean 實例化之前提前實例化
          @Override
          public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
              PrimaryOrderBean bean = beanFactory.getBean(PrimaryOrderBean.class);
              System.out.println(bean);
          }
      }
      @Component
      public class PrimaryOrderBean {
      
          public PrimaryOrderBean() {
              System.out.println("init primary order bean");
          }
      
          @Override
          public String toString() {
              return "PrimaryOrderBean{toString}";
          }
      }
      

      此方式的風險:可讀性差,容易踩坑,除非寫框架,否則不建議

      5、 @AutoConfigureBefore / @AutoConfigureAfter(僅對 spring.factories 里的自動配置生效)

      當在寫自己的 starter時,想讓 MyAutoConfigurationDataSourceAutoConfiguration 之前/之后運行。
      對普通 @Configuration 無效,也不會影響 Bean 實例化順序,只影響配置類解析順序。

      @Configuration
      @AutoConfigureBefore(DataSourceAutoConfiguration.class)
      public class MyAutoConfiguration { }
      

      這兩個注解只對 META-INF/spring.factories 中注冊的 EnableAutoConfiguration 類生效;寫在普通 @Configuration 類上會被忽略。

      6、實現 PriorityOrdered / Ordered(只影響“后處理”順序)

      對普通 Bean 的“實例化順序”沒有任何影響,僅當 Spring 內部收集 BeanPostProcessorFactoryPostProcessor 等擴展點時使用。

      posted @ 2025-11-04 16:32  紀莫  閱讀(96)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产一区国产二区在线视频| 亚洲国产制服丝袜先锋| 亚洲色大成网站www永久男同| 国产美女被遭强高潮免费一视频| 99久久婷婷国产综合精品青草漫画| 国产最大的福利精品自拍| 伊人久久大香线蕉AV网禁呦| 男女性高爱潮免费网站| 日本一区二区精品色超碰| 新版天堂资源中文8在线| 国产特级毛片aaaaaa毛片| 国产一区在线播放无遮挡| 色综合久久一区二区三区| 亚洲人妻一区二区精品| 五莲县| 三上悠亚日韩精品二区| 国产亚洲精品久久77777| 国产精品无码专区| 成人性生交片无码免费看| 成熟丰满熟妇av无码区| 久久久久人妻精品一区三寸| 亚洲另类无码一区二区三区| 精品国产欧美一区二区五十路| 美女又黄又免费的视频| 少妇高潮激情一区二区三| 亚洲欧洲一区二区三区久久| 久久天天躁狠狠躁夜夜avapp | 久久人妻无码一区二区三区av| 亚洲av日韩av综合在线观看| 久久精品国产成人午夜福利| 日本黄页网站免费观看| 国产综合色一区二区三区| 麻豆国产成人AV在线播放| 常山县| 一级做a爰片在线播放| 精品尤物TV福利院在线网站| 天堂mv在线mv免费mv香蕉| 精品国产成人国产在线视| 国产午夜亚洲精品一区| 风韵丰满熟妇啪啪区老熟熟女| 小污女小欲女导航|