日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

我們使用Springboot進行開發的時候發現真的很方便,我們只需要很少的配置、少量的注解以及引入一些starter就可以完成一個簡單項目的開發。使我們受益的就是Springboot的自動配置功能,下面我們來探索Springboot的自動配置原理。(中間的一些細節的地方不做過多介紹,影響閱讀體驗,主要解析核心脈絡

先看下配置類的解析流程圖:

Springboot——自動配置原理

配置類解析流程圖

我們知道Spring容器的主要工作原理就是先根據配置的信息將相關的BeanDefinition(也就是Bean的元數據,比如類的全路徑名、屬性等)掃描并加載到容器中,后續再根據這些BeanDefinition對這些Bean進行實例化初始化等一系列操作,然后再將最后的Bean實例保存到Spring容器中。因此Springboot的自動配置的原理主要是BeanDefinition的自動注冊

我們就從Springboot的啟動類TomcatWarApplication開始分析:

package com.sourcecode.springboot.tomcatwar;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class TomcatWarApplication {
    public static void main(String[] args) {
        SpringApplication.run(TomcatWarApplication.class, args);
    }
}

步驟分析:

第一步:main方法的作用就是新建一個SpringApplication實例并將將TomcatWarApplication.class放入到了該對象的實例屬性primarySources(一個Set)中,然后調用該對象的run方法

第二步:run方法中會對primarySources中的存放的TomcatWarApplication.class進行加載并解析為一個BeanDefinition后注冊到BeanFactory中

第三步【重點】:run方法內部的refreshContext方法會對BeanFactory中的BeanDefinition進行處理,將該BeanDefinition的注解元數據和對應的bean名稱封裝為一個ConfigurationClass(配置類)對象,然后對該對象進行解析。具體步驟如下:

  1. 類是否有@Component注解,如果有的話,解析該類的成員內部類是否滿足作為一個配置類的要求(該內部類是否有@Component、@ComponentScan、@Import、@ImportResource注解或者該內部類是否有被@Bean注解的方法),如果滿足的話,那么就將該內部類作為一個配置類進行同樣的解析
  2. 類是否有@PropertySource注解,用來解析properties配置文件中配置的屬性
  3. 類是否有@ComponentScan注解,如果有的話,解析該注解相應屬性中配置的包名、類的全路徑所在的包名,然后使用ClassPathBeanDefinitionScanner掃描器對這些類路徑下的class文件進行加載解析,判斷這些class是否滿足條件(是否有@Component注解、是否有@JAVAx.annotation.ManagedBean注解、是否有@javax.inject.Named注解),如果滿足條件的話,就將該class作為一個配置類進行同樣的解析
  4. 類是否有@Import注解a)如果@Import注解中的value屬性值是ImportSelector類型的話,再判斷是否是延遲導入選擇器DeferredImportSelector類型的,如果是的話,那么延遲處理value屬性值對應的class,最終調用的是processGroupImports方法;如果不是延遲導入類型,那么立即對value屬性值對應的class進行處理,最終調用的是該類的selectImports方法,然后將該方法返回的所有的類名作為配置類進行同樣的解析;b)如果@Import注解中的value屬性值是ImportBeanDefinitionRegistrar類型的,則后續調用registerBeanDefinitions進行BeanDefinition的注冊;c)如果是其他類型的class,那么就直接將該class作為一個配置類進行同樣的解析
  5. 類是否有@ImportResource注解,如果有的話,就導入以XML格式進行BeanDefinition定義的配置文件,后續把該配置文件中定義的BeanDefinition作為配置類進行同樣的解析
  6. 類中是否有被@Bean注解的方法,如果有的話,抽取這些方法的元數據并添加到該配置類的屬性中,后續實例化時也會實例化以方法的形式聲明的Bean
  7. 如果類實現了接口,抽取這些接口中被@Bean注解了的默認方法(default method)的元數據并添加到該配置類的屬性中,后續實例化時也會實例化這些以方法的形式聲明的Bean
  8. 如果該類有父類的話,那么把父類相關信息也封裝為一個ConfigurationClass并做同上述一樣的解析

第四步:通過上述步驟之后,就把TomcatWarApplication.class以及它關聯的所有BeanDefinition注冊到BeanFactory中了,后面進行Bean的實例化的時候就會根據所有注冊的BeanDefinition來進行對應的實例化

回到我們的啟動類,我們將@SpringBootApplication的一些相關元注解全部提取出來放在一起,這些看起來清晰一些:

@Configuration
@Import(AutoConfigurationImportSelector.class)
@Import(AutoConfigurationPackages.Registrar.class)
@ComponentScan
public class TomcatWarApplication {
    public static void main(String[] args) {
        SpringApplication.run(TomcatWarApplication.class, args);
    }
}

這樣看發現我們的啟動類實際是被這些注解標識:

@Configuration

@Import(AutoConfigurationImportSelector.class)

@Import(AutoConfigurationPackages.Registrar.class)

@ComponentScan

我們按我們上面步驟的第三步來對TomcatWarApplication.class這個配置類進行解析:

1、@ComponentScan滿足第三個條件,如果@ComponentScan注解沒有顯示設置的屬性,那么就掃描TomcatWarApplication所在包路徑(com.sourcecode.springboot.tomcatwar)下的class,如果滿足條件(比如注解了@Configuration或@Service等)就會將這些class作為一個配置類,然后進行同樣的解析

2、@Import(AutoConfigurationImportSelector.class),這個Selector是ImportSelector類型且是DeferredImportSelector類型,那么就將AutoConfigurationImportSelector中的selectImports方法返回的類作為配置類進行同樣解析,該方法使用SPI的方式從jar中的META-INF/spring.factories文件中獲取指定屬性的值(也就是對應類的全路徑名稱為屬性名),然后將這些類作為配置類進行同樣的解析,一些starter的定義就是使用這種方式(比如Druid數據源的starter),如下所示:

Springboot——自動配置原理

SPI


Springboot——自動配置原理

自動配置


Springboot——自動配置原理

druid數據源的starter

3、@Import(AutoConfigurationPackages.Registrar.class)該Registrar是ImportSelector類型但不是延遲導入類型,so調用該類的registerBeanDefinitions方法進行注冊BeanDefinition,比如Mybatis的注解@MapperScan

Springboot——自動配置原理

@MapperScan注解

再來看@Import中的MapperScannerRegistrar,最終通過registerBeanDefinitions方法來對我們定義的Mapper/Dao進行掃描并注冊BeanDefinition到BeanFactory中

Springboot——自動配置原理

MapperScannerRegistrar

通過對Springboot自動配置的的分析,我們就可以定義我們自己組件的starter了~~~

再次回顧下配置類的解析流程圖吧:

Springboot——自動配置原理

配置類解析流程圖

覺得可以的話點個關注加個收藏唄,陸續奉上干貨~~~~

分享到:
標簽:配置 SpringBoot
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定