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

一文徹底弄懂Spring?Boot自動配置

 更新時間:2025年11月03日 08:45:20   作者:楠枬  
在SpringBoot框架中自動配置是其最核心的特性之一,也是"約定優(yōu)于配置"理念的集中體現(xiàn),這篇文章主要介紹了Spring?Boot自動配置的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

什么是自動配置?

Spring Boot 的自動配置:當(dāng) Spring 容器啟動后,一些配置類、bean 對象等就自動存入 Ioc 容器中,而不再需要我們手動去聲明,從而簡化了程序開發(fā)過程,省去了繁瑣的配置操作

也就是說,Spring Boot 的自動配置,就是 SpinrgBoot 依賴 jar 包中的配置類以及 Bean 加載到 Spring Ioc 容器中的過程

在本篇文章中,我們主要學(xué)習(xí)一下兩個方面:

1. Spring 如何將對象加載到 Spring Ioc 容器中

2. SpringBoot 是如何進(jìn)行實現(xiàn)的

我們首先來看 Spring 是如何加載 Bean 的

Spring 加載 Bean

當(dāng)我們在項目中引入第三方的包時,其實就是在該項目下引入第三方的代碼,我們通過在該項目下創(chuàng)建不同的目錄來模擬第三方代碼的引入:

當(dāng)前項目目錄為 com.example.springautoconfig,模擬第三方代碼文件在 com.example.autoconfig 目錄下 

第三方文件代碼:

@Component
public class AutoConfig {
    public void test() {
        System.out.println("test...");
    }
}

獲取 AutoConfig:

@SpringBootTest
class SpringAutoconfigApplicationTests {
    @Autowired
    private ApplicationContext context;
    @Test
    void contextLoads() {
        AutoConfig bean = context.getBean(AutoConfig.class);
        System.out.println(bean);
    }
}

運行結(jié)果:

此時顯示沒有 com.example.autoconfig.AutoConfig 這個類型的 bean

為什么會報錯呢?

Spring 使用 類注解(@Controller、@Service、@Repository、@Component、@Configuration) 和 @Bean 注解 幫助我們將 Bean 加載到 Spring Ioc 容器中時,有一個前提:這些注解需要和 SpringBoot 啟動類(@SpringBootApplication 標(biāo)注的類)在同一個目錄下

而在上述項目中,啟動類所在目錄為  com.example.springautoconfig,而 AutoConfig 類位于 com.example.autoconfig 目錄下,因此,SpringBoot 并沒有掃描到

可是,當(dāng)我們引入第三方的 jar 包時,第三方的 jar 代碼目錄也不在啟動類的目錄下,那么,如何讓 Spring 幫我們管理這些 Bean 的呢?

我們可以通過指定路徑或引入的文件告訴 Spring,讓 Spring 進(jìn)行掃描

常見的實現(xiàn)方法有兩種:

1. @ComponentScan 組件掃描

2. @Import 導(dǎo)入

@ComponentScan

使用 @ComponentScan 注解,指定 Spring 掃描路徑:

@SpringBootApplication
@ComponentScan("com.example.autoconfig")
public class SpringAutoconfigApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringAutoconfigApplication.class, args);
    }
}

運行程序并觀察結(jié)果:

 成功獲取到 AutoConfig bean

那么,Spring Boot 是否使用了這種方式呢?

顯然沒有。若 Spring Boot 采用這種方式,當(dāng)我們引入大量的第三方依賴,如 MyBatis、jackson 等時,就需要在啟動類上配置不同依賴需要掃描的包,非常繁瑣

@Import

@Import 導(dǎo)入主要有以下幾種形式:

1. 導(dǎo)入類

2. 導(dǎo)入 ImportSelector 接口的實現(xiàn)類

導(dǎo)入類

@Import(AutoConfig.class)
@SpringBootApplication
public class SpringAutoconfigApplication {

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

}

運行程序,觀察結(jié)果:

成功獲取到 AutoConfig Bean

若在文件中有多個配置項:

@Component
public class AutoConfig2 {
    public void test() {
        System.out.println("test...");
    }
}

此時就需要導(dǎo)入多個類:

@Import({AutoConfig.class, AutoConfig2.class})
@SpringBootApplication
public class SpringAutoconfigApplication {

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

}

顯而易見,這種方式也比較繁瑣,因此,Spring Boot 也沒有采用

導(dǎo)入 ImportSelector 接口的實現(xiàn)類

實現(xiàn) ImportSelector 接口:

public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        // 返回需要導(dǎo)入的全限定類名
        return new String[]{"com.example.autoconfig.AutoConfig", "com.example.autoconfig.AutoConfig2"};
    }
}

導(dǎo)入:

@Import(MyImportSelector.class)
@SpringBootApplication
public class SpringAutoconfigApplication {

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

}

運行程序,并觀察結(jié)果:

這種方式也可以導(dǎo)入第三方依賴提供的 Bean

但是,它們都有一個明顯的問題:使用者需要知道第三方依賴中有哪些 Bean 對象或配置類,若我們在導(dǎo)入過程中漏掉了一些 Bean,就可能會導(dǎo)致我們的項目出現(xiàn)問題

依賴中有哪些 Bean,使用時需要配置哪些 Bean,這些問題第三方依賴最為清楚,那么,能否由第三方依賴來做這些事情呢?

比較常見的方法是第三方依賴提供一個注解,而這個注解一般是以 @EnableXxx 開頭的注解,而注解中封裝的就是 @Import 注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
// 指定要導(dǎo)入哪些類
@Import(MyImportSelector.class)
public @interface EnableAutoConfig {
}

在啟動類上使用第三方提供的注解:

@EnableAutoConfig
@SpringBootApplication
public class SpringAutoconfigApplication {

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

}

運行并觀察結(jié)果:

可以看到,這種方式也可以導(dǎo)入第三方依賴提供的 Bean,且這種方式不需要使用方知道第三方依賴中有哪些 Bean 對象或配置類,而在 Spring Boot 中也是使用的這種方式

SpringBoot 原理分析

SpringBoot 是如何進(jìn)行實現(xiàn)的?讓我們從 SpringBoot 的啟動類開始看:

由 @SpringBootApplication 標(biāo)注的類就是 SpringBoot 項目的啟動類:

這個類與普通類的唯一區(qū)別就是 @SpringBootApplication 注解,這個注解也是 SpringBoot 實現(xiàn)自動配置的核心

 @SpringBootApplication 是一個組合注解,注解中包含了:

1. 元注解:

 JDK 中提供了 4 個 標(biāo)準(zhǔn)的用來對注解類型進(jìn)行注解的注解類,稱之為 meta-annotation(元注解)

分別為:

@Retention:描述注解保留的時間范圍

@Target:描述注解的使用范圍

@Documented:描述在使用 javadoc 工具為類生成幫助文檔時是否保留其注解信息

@Inherited:使被其修飾的注解具有繼承性(若某個類使用了 @Inherited,則其子類將自動具有該注解)

2. @SpringBootConfiguration: 

標(biāo)識當(dāng)前類是一個配置類,里面其實就是 @Configuration,只是做了進(jìn)一步的封裝

其中,@Indexed 注解是用來加速應(yīng)用啟動的

3. @EnableAutoConfiguration(開啟自動配置)

是 spiring 自動配置的核心注解,我們在后續(xù)詳細(xì)理解

4.  ComponentScan(包掃描)

可以通過 basePackageClasses basePackages 來定義要掃描的特定包,若沒有定義特定的包,將從聲明該注解的類的包開始掃描,這也是 SpringBoot 項目聲明的注解類為什么必須在啟動類目錄下

也可以自定義過濾器,用于排查一些類、注解等

接下來,我們重點來看  @EnableAutoConfiguration(開啟自動配置)

@EnableAutoConfiguration

 @EnableAutoConfiguration 中主要包含兩部分:

@Import(AutoConfigurationImportSelector.class) 

@AutoConfigurationPackage

我們先來看  @Import(AutoConfigurationImportSelector.class) 

@Import(AutoConfigurationImportSelector.class)

使用 @Import 注解,導(dǎo)入了實現(xiàn) ImportSelector 接口的實現(xiàn)類:

selectImports() 方法中,調(diào)用了 getAutoConfigurationEntry() 方法,獲取可自動配置的配置類信息

我們繼續(xù)看  getAutoConfigurationEntry() 方法:

在  getAutoConfigurationEntry() 方法中,主要通過 getCandidateConfigurations(annotationMetadata, attributes) 方法 和 fireAutoConfigurationImportEvents(configurations, exclusions) 方法,獲取在配置文件中配置的所有自動配置類的集合

我們先看  getCandidateConfigurations(annotationMetadata, attributes) 方法:

在 getCandidateConfigurations(annotationMetadata, attributes) 方法中,使用 ImportCandidates 進(jìn)行加載

那么,從哪里進(jìn)行加載呢?

從 斷言 的錯誤信息中我們可以找到答案:META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

也就是說, getCandidateConfigurations 方法會獲取所有基于META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件中配置類的集合

META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件:

 其中包含了很多第三方依賴的配置文件 

我們以 redis 為例:

查看 RedisAutoConfiguration

可以看到,在使用 redis 時常用的 RedisTemplate 和 StringRedisTemplate 就位于其中,在我們需要使用時直接使用 @Autowired 進(jìn)行注入就可以了

但是,由于當(dāng)前項目并沒有引入 redis 相關(guān) jar 包,此時這個類并不能被加載

也就是說在加載自動配置類的時候,并不是將所有的配置全部加載進(jìn)來,而是會先進(jìn)行判斷,根據(jù) @ConditionalOnMissingBean@ConditionalOnSingleCandidate 等注解的判斷進(jìn)行動態(tài)加載

即,在配置文件中使用 @Bean 聲明對象,spring 會自動調(diào)用配置類中使用 @Bean 標(biāo)識的方法,并將對象存放到 Spring Ioc 中,但是,在加載自動配置類的時候,并不是將所有的配置全部加載進(jìn)來,而是會通過 @Conditional 等注解的判斷進(jìn)行動態(tài)加載@Conditional 是 spring 底層注解,會根據(jù)不同的條件,進(jìn)行條件判斷,若滿足指定條件,配置類中的配置才會生效)

我們繼續(xù)看 fireAutoConfigurationImportEvents 方法,找到是從哪里獲取配置類的:

可以看到,fireAutoConfigurationImportEvents 方法最終會從 META-INF/spring.factories 中獲取配置類的集合

我們來看 META-INF/spring.factories

META-INF/spring.factories 文件是 Spring 內(nèi)部提供的一個約定俗稱的加載方式,只需要在模塊的 META-INF/spring.factories 文件中進(jìn)行配置,Spring 就會把相應(yīng)的實現(xiàn)類注入到 Spring 容器中

例如,有一個自動配置類,希望 SpringBoot 在啟動時自動加載這個配置,我們就可以在 META-INF/spring.factories 文件按照指定格式進(jìn)行配置,讓 Spring Boot 應(yīng)用啟動時,讀取這個 spring.factories 文件,根據(jù)文件中指定的配置類來進(jìn)行自動配置

spring 會加載所有 jar 包下的 META-INF/spring.factories 文件

META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports   META-INF/spring.factories 都在引入的起步依賴中:

我們繼續(xù)看  AutoConfigurationPackage

AutoConfigurationPackage

在這個注解中,主要導(dǎo)入了一個配置文件 AutoConfigurationPackages.Registrar.class

我們繼續(xù)看 Registrar

 Registrar 實現(xiàn)了 ImportBeanDefinitionRegistrar 接口,可以被 @Import 導(dǎo)入到 spring 容器中

new PackageImports(metadata).getPackageNames().toArray(new String[0]): 當(dāng)前啟動類所在的包名

也就是說,@AutoConfigurationPackage 的作用是 將啟動類所在的包下面所有的組件都掃描注冊到 spring 容器中

最后,我們來總結(jié)一下 SpringBoot 自動配置的流程

SpringBoot 自動配置流程

 SpringBoot 的自動配置的入口是  @SpringBootApplication 注解,在這個注解中,主要封裝了 3 個注解:

@SpringBootConfiguration:標(biāo)識當(dāng)前類是配置類

@ComponentScan(包掃描):可以通過 basePackageClasses basePackages 定義要掃描的特定包,若沒有定義特定的包,將從聲明該注解的類的包開始掃描,也就是說,默認(rèn)情況下掃描的是啟動類所在的當(dāng)前包以及子包

@EnableAutoConfiguration(開啟自動配置):主要包含兩部分:

@Import(AutoConfigurationImportSelector.class) :讀取 META-INF/spring.factories 和  META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件中定義的配置類????

@AutoConfigurationPackage:將啟動類所在的包下所有組件都注入到 Spring 容器中

總結(jié)

到此這篇關(guān)于Spring Boot自動配置的文章就介紹到這了,更多相關(guān)Spring Boot自動配置內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

定安县| 雅安市| 江源县| 子洲县| 鱼台县| 久治县| 抚顺县| 阜阳市| 浑源县| 邳州市| 南和县| 剑川县| 丹棱县| 石渠县| 曲阳县| 武定县| 灵武市| 江口县| 孟村| 紫阳县| 隆子县| 孟连| 佛学| 宁都县| 连山| 武安市| 定结县| 吕梁市| 巴楚县| 富源县| 宝丰县| 芮城县| 南充市| 通道| 固安县| 大姚县| 桦南县| 渝北区| 宿州市| 桂阳县| 新巴尔虎左旗|