最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Boot 的注解生效詳細(xì)步驟解析

 更新時間:2025年09月11日 11:21:15   作者:許苑向上  
Spring通過掃描、解析、注冊分層處理配置類注解(如@Configuration、@ComponentScan等),利用遞歸、延遲加載和緩存機(jī)制,實(shí)現(xiàn)BeanDefinition的動態(tài)注冊與靈活擴(kuò)展,解決依賴和性能問題,本文給大家介紹Spring Boot的注解生效詳細(xì)步驟解析,感興趣的朋友跟隨小編一起看看吧

在 Spring 中,@Configuration@ComponentScan、@Bean@Import 等注解的掃描、解析和 BeanDefinition 注冊是一個分層處理的過程。下面我們以 @Configuration為例,結(jié)合代碼流程詳細(xì)說明其從掃描到注冊的完整邏輯。

1. 整體流程概覽

以下是核心步驟的流程圖:

1. 掃描候選配置類 → 2. 解析注解元數(shù)據(jù) → 3. 注冊 BeanDefinition

具體分為以下階段:

  1. 掃描階段:通過 BeanDefinitionRegistry 獲取所有候選配置類。
  2. 解析階段:使用 ConfigurationClassParser 解析注解(如 @ComponentScan、@Bean、@Import)。
  3. 注冊階段:通過 ConfigurationClassBeanDefinitionReader 將解析結(jié)果注冊為 BeanDefinition

2. 詳細(xì)步驟解析

2.1 掃描階段:識別候選配置類

觸發(fā)入口
ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry()
邏輯

  1. BeanDefinitionRegistry 獲取所有已注冊的 BeanDefinition 名稱:
    String[] beanNames = registry.getBeanDefinitionNames();
  2. 遍歷這些名稱,檢查對應(yīng)的 BeanDefinition 是否是候選配置類:
    • 條件:類上有 @Configuration、@Component、@ComponentScan、@Import、@ImportResource,或類中有 @Bean 方法。
    • 判斷邏輯
      if (isFullConfigurationCandidate(beanDef) || isLiteConfigurationCandidate(beanDef)) {
          configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
      }
      
    • isFullConfigurationCandidate(beanDef):檢查是否有 @Configuration 注解。
    • isLiteConfigurationCandidate(beanDef):檢查是否有其他相關(guān)注解(如 @Component@Bean 方法)。

關(guān)鍵點(diǎn)

  • 掃描的輸入是已注冊的 BeanDefinition(可能來自 XML、Java Config 或自動掃描)。
  • 此時尚未解析注解內(nèi)容,僅識別出需要進(jìn)一步處理的候選類。

2.2 解析階段:處理注解元數(shù)據(jù)

核心類ConfigurationClassParser
入口方法parse()
邏輯:遞歸解析每個候選配置類的注解。

(1) 解析@ComponentScan

  • 作用:掃描指定包路徑下的 @Component 類(如 @Service、@Repository)。
  • 流程
    1. 獲取 @ComponentScan 注解的 basePackagesbasePackageClasses。
    2. 使用 ClassPathBeanDefinitionScanner 掃描類路徑:
      scanner.scan(basePackages);
    3. 掃描到的類會被注冊為新的 BeanDefinition(類型為 ScannedGenericBeanDefinition)。
  • 關(guān)鍵點(diǎn)
    • 掃描時使用 ASM 或反射讀取類注解,避免提前加載類到 JVM。
    • 新注冊的 BeanDefinition 可能也會被后續(xù)解析(如果它們也是配置類)。

(2) 解析@Bean方法

  • 作用:將配置類中的 @Bean 方法轉(zhuǎn)換為 BeanDefinition。
  • 流程
    1. 遍歷配置類中的所有方法,篩選帶 @Bean 注解的方法。
    2. 為每個 @Bean 方法生成一個 BeanDefinition
      • 類型ConfigurationClassBeanDefinition。
      • 工廠方法:設(shè)置為 @Bean 方法(通過 factoryMethodNamefactoryBeanName 指定)。
      • 依賴:解析 @Bean 方法的參數(shù)(按類型或 @Qualifier 注入)。
  • 示例
    @Configuration
    public class AppConfig {
        @Bean
        public DataSource dataSource() {
            return new HikariDataSource();
        }
    }
    • 生成的 BeanDefinition 會記錄:factoryBeanName=appConfig, factoryMethodName=dataSource。

(3) 解析@Import

  • 作用:動態(tài)導(dǎo)入其他配置類或 BeanDefinition。
  • 三種處理方式
    1. 普通類:直接注冊為 BeanDefinition。
      @Import(OtherConfig.class)
      
    2. ImportSelector:通過編程方式選擇要導(dǎo)入的類。
      @Import(MyImportSelector.class)
      
      • MyImportSelector 實(shí)現(xiàn) selectImports() 方法,返回要導(dǎo)入的類名數(shù)組。
    3. ImportBeanDefinitionRegistrar:直接注冊 BeanDefinition
      @Import(MyRegistrar.class)
      
      • MyRegistrar 實(shí)現(xiàn) registerBeanDefinitions() 方法,手動操作 BeanDefinitionRegistry

(4) 處理父類與接口

  • 遞歸檢查配置類的父類和接口,確保不遺漏任何 @Bean 方法或元注解。

2.3 注冊階段:加載BeanDefinition

核心類ConfigurationClassBeanDefinitionReader
入口方法loadBeanDefinitions()
邏輯:將解析結(jié)果(ConfigurationClass 對象)轉(zhuǎn)換為 BeanDefinition 并注冊到容器。

(1) 注冊@Import的類

  • 普通類:通過 registry.registerBeanDefinition() 直接注冊。
  • ImportBeanDefinitionRegistrar:調(diào)用其 registerBeanDefinitions() 方法。

(2) 注冊@Bean方法

  • 為每個 @Bean 方法生成 BeanDefinition 并注冊:
    for (BeanMethod beanMethod : configClass.getBeanMethods()) {
        loadBeanDefinitionsForBeanMethod(beanMethod);
    }

(3) 處理嵌套配置類

  • 如果配置類內(nèi)部有 @Configuration 靜態(tài)嵌套類,遞歸處理。

3. 關(guān)鍵設(shè)計(jì)點(diǎn)

(1) 延遲加載與遞歸處理

  • 延遲加載@ComponentScan 掃描到的類可能也是配置類,需要遞歸解析。
  • 循環(huán)依賴處理:Spring 通過提前暴露 BeanDefinition 解決配置類之間的循環(huán)引用。

(2) 元數(shù)據(jù)存儲

  • ConfigurationClass 對象存儲解析后的中間結(jié)果(如 @Bean 方法、@Import 類等)。
  • BeanDefinitionattribute 字段存儲配置類的元信息(如 @Lazy、@Primary)。

(3) 性能優(yōu)化

  • ASM 字節(jié)碼分析:在掃描階段避免加載類到 JVM。
  • 緩存:解析結(jié)果緩存到 ConfigurationClass 中,避免重復(fù)處理。

4. 示例全流程

場景

@Configuration
@ComponentScan("com.example.service")
@Import(OtherConfig.class)
public class AppConfig {
    @Bean
    public DataSource dataSource() {
        return new HikariDataSource();
    }
}

步驟

  1. 掃描階段
    • 發(fā)現(xiàn) AppConfig 是候選配置類(有 @Configuration)。
  2. 解析階段
    • 解析 @ComponentScan:掃描 com.example.service 包,注冊 @Service 類。
    • 解析 @Import(OtherConfig.class):遞歸處理 OtherConfig。
    • 解析 @Bean dataSource():生成工廠方法 BeanDefinition
  3. 注冊階段
    • 注冊 OtherConfig 及其 @Bean 方法。
    • 注冊 dataSourceBeanDefinition。

5. 總結(jié)

Spring 對配置類注解的處理是一個分層遞歸的過程:

  1. 掃描:通過 BeanDefinitionRegistry 篩選候選類。
  2. 解析ConfigurationClassParser 解析注解并生成中間結(jié)果(ConfigurationClass)。
  3. 注冊ConfigurationClassBeanDefinitionReader 將解析結(jié)果轉(zhuǎn)換為 BeanDefinition

這種設(shè)計(jì)將注解元數(shù)據(jù)解析與 BeanDefinition 注冊分離,確保了靈活性和擴(kuò)展性(如支持動態(tài) ImportSelector)。同時,遞歸處理和緩存機(jī)制解決了復(fù)雜依賴和性能問題。

到此這篇關(guān)于Spring Boot 的注解生效詳細(xì)步驟解析的文章就介紹到這了,更多相關(guān)Spring Boot 注解生效內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Maven在Java8下如何忽略Javadoc的編譯錯誤詳解

    Maven在Java8下如何忽略Javadoc的編譯錯誤詳解

    這篇文章主要給大家介紹了關(guān)于Maven在Java8下如何忽略Javadoc的編譯錯誤的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08
  • Java的CollectionUtils工具類詳解

    Java的CollectionUtils工具類詳解

    這篇文章主要介紹了Java的CollectionUtils工具類詳解,CollectionUtils工具類是在apache下的,而不是springframework下的,個人覺得在真實(shí)項(xiàng)目中CollectionUtils,可以使你的代碼更加簡潔和安全,需要的朋友可以參考下
    2023-05-05
  • Java synchronized偏向鎖的核心原理詳解

    Java synchronized偏向鎖的核心原理詳解

    這篇文章主要為大家詳細(xì)介紹了Java synchronized偏向鎖的核心原理,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • java封裝全局異常處理深入詳解

    java封裝全局異常處理深入詳解

    這篇文章主要為大家介紹了java封裝全局異常處理的深入詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • java?JVM方法分派模型靜態(tài)分派動態(tài)分派全面講解

    java?JVM方法分派模型靜態(tài)分派動態(tài)分派全面講解

    這篇文章主要為大家介紹了java?JVM方法分派模型靜態(tài)分派動態(tài)分派全面講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • springboot配置templates直接訪問的實(shí)現(xiàn)

    springboot配置templates直接訪問的實(shí)現(xiàn)

    這篇文章主要介紹了springboot配置templates直接訪問的實(shí)現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • SpringBoot自定義定時任務(wù)的實(shí)現(xiàn)示例

    SpringBoot自定義定時任務(wù)的實(shí)現(xiàn)示例

    本文主要介紹了SpringBoot自定義定時任務(wù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • 前后端分離跨域springBoot跨域有效解決問題

    前后端分離跨域springBoot跨域有效解決問題

    這篇文章主要介紹了前后端分離跨域springBoot跨域有效解決問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • 詳解Java數(shù)組擴(kuò)容縮容與拷貝的實(shí)現(xiàn)和原理

    詳解Java數(shù)組擴(kuò)容縮容與拷貝的實(shí)現(xiàn)和原理

    這篇文章主要帶大家學(xué)習(xí)數(shù)組的擴(kuò)容、縮容及拷貝,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • Spring Boot conditional注解用法詳解

    Spring Boot conditional注解用法詳解

    這篇文章主要介紹了Spring Boot conditional注解用法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-03-03

最新評論

怀化市| 张家港市| 汤原县| 金塔县| 图木舒克市| 揭东县| 凉山| 武宁县| 繁峙县| 尼木县| 旌德县| 中宁县| 宜丰县| 城口县| 武穴市| 芮城县| 郯城县| 绥阳县| 奎屯市| 鄯善县| 伊宁县| 岳池县| 五指山市| 克什克腾旗| 老河口市| 秦安县| 黄陵县| 盖州市| 潮安县| 南和县| 大竹县| 饶阳县| 青海省| 武定县| 汉源县| 博湖县| 漳州市| 任丘市| 沙田区| 曲周县| 茶陵县|