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

SpringBoot原理之自動(dòng)配置機(jī)制詳解

 更新時(shí)間:2021年11月12日 16:53:41   作者:青溟  
Springboot遵循“約定優(yōu)于配置”的原則,使用注解對(duì)一些常規(guī)的配置項(xiàng)做默認(rèn)配置,減少或不使用xml配置,讓你的項(xiàng)目快速運(yùn)行起來(lái),下面這篇文章主要給大家介紹了關(guān)于SpringBoot原理之自動(dòng)配置機(jī)制的相關(guān)資料,需要的朋友可以參考下

前言

在當(dāng)下的java生態(tài)里,SpringBoot已經(jīng)成為事實(shí)上的開(kāi)發(fā)標(biāo)準(zhǔn),絕大多數(shù)人現(xiàn)在都是面向SpringBoot編程。SpringBoot是對(duì)Spring的進(jìn)一步封裝,整合了分布式系統(tǒng)上下游所需的各種類(lèi)庫(kù)和組件,并且實(shí)現(xiàn)了開(kāi)箱即用,而這一切的底層基礎(chǔ)就是SpringBoot的自動(dòng)配置機(jī)制。

Spring配置類(lèi)

Spring引入配置類(lèi)是為了:1)替換冗長(zhǎng)繁瑣的配置文件,2)提供更靈活的bean定義方式。使用@Configuration注解去標(biāo)記一個(gè)配置類(lèi),通過(guò)其中含有@Bean注解的方法去創(chuàng)建一個(gè)bean,如下代碼

@Configuration
public class HelloAutoConfiguration {

    @Bean
    HelloService helloService() {
        return new HelloService;
    }

}

即為一個(gè)簡(jiǎn)單的配置類(lèi),并且定義了一個(gè)HelloService的bean。在此之上,Spring還提供了一套條件加載機(jī)制,可以去動(dòng)態(tài)控制一個(gè)配置類(lèi)是否被加載。通過(guò)實(shí)現(xiàn)org.springframework.context.annotation.Condition接口,開(kāi)發(fā)者就可以自己控制配置類(lèi)的加載條件,滿足很多復(fù)雜的場(chǎng)景

SpringBoot自動(dòng)配置

介紹完了Spring的配置類(lèi),我們來(lái)看看SpringBoot是怎么利用這套機(jī)制去實(shí)現(xiàn)自動(dòng)配置的。

自動(dòng)配置的概念

首先,什么是自動(dòng)配置?我們看一下SpringBoot對(duì)于自動(dòng)配置類(lèi)的定義:

Auto-configuration classes are regular Spring @Configuration beans. They are located using the SpringFactoriesLoader mechanism (keyed against this class). Generally auto-configuration beans are @Conditional beans (most often using @ConditionalOnClass and @ConditionalOnMissingBeanannotations).

自動(dòng)配置類(lèi)就是一個(gè)普通的@Configuration配置類(lèi),通常會(huì)帶有一些@Conditional條件注解,并且使用SpringFactoriesLoader機(jī)制去定位加載它們(并非都是如此,還有其他一些Spring固有的加載方式,比如通過(guò)@ComponentScan包掃描或者顯式@Import方式都可以讓它們被發(fā)現(xiàn))。

自動(dòng)配置的運(yùn)行機(jī)制

加載方式

自動(dòng)配置機(jī)制的啟用是通過(guò)@EnableAutoConfiguration注解去控制的,因此需要在SpringBoot工程的入口類(lèi)上啟用該注解,但是通常,我們一般使用@SpringBootApplication來(lái)代替,后者是一個(gè)注解的合集,包含了一些必要的默認(rèn)配置,其中就有@EnableAutoConfiguration注解,其類(lèi)的注釋上是這么描述的:

Indicates a Configuration class that declares one or more @Bean methods and also triggers auto-configuration and component scanning. This is a convenience annotation that is equivalent to declaring @Configuration, @EnableAutoConfiguration and @ComponentScan.

它本身既標(biāo)識(shí)一個(gè)配置類(lèi),同時(shí)也開(kāi)啟了自動(dòng)配置和組件掃描。

回到@EnableAutoConfiguration注解上,我們看一下該注解的定義

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

    Class<?>[] exclude() default {};

    String[] excludeName() default {};
}

其中@Import(AutoConfigurationImportSelector.class)是功能生效的關(guān)鍵,該注解導(dǎo)入了AutoConfigurationImportSelector組件到Spring環(huán)境中,開(kāi)啟自動(dòng)配置類(lèi)的掃描加載工作,該類(lèi)實(shí)現(xiàn)了接口org.springframework.context.annotation.ImportSelector

public interface ImportSelector {

    /**
     * Select and return the names of which class(es) should be imported based on
     * the {@link AnnotationMetadata} of the importing @{@link Configuration} class.
     * @return the class names, or an empty array if none
     */
    String[] selectImports(AnnotationMetadata importingClassMetadata);

   ....其他省略
}

其中selectImports方法會(huì)在Spring啟動(dòng)時(shí)被調(diào)用,用于返回所有的自動(dòng)配置類(lèi),調(diào)用入口在org.springframework.context.annotation.ConfigurationClassParser類(lèi)中,該類(lèi)是Spring專(zhuān)門(mén)用來(lái)加載處理所有@Configuration配置類(lèi)的,具體的加載細(xì)節(jié),限于篇幅問(wèn)題,就不在本文中展開(kāi)說(shuō)明了,讀者們可自行去閱讀源碼,本人也許會(huì)在后續(xù)再另開(kāi)一篇詳細(xì)說(shuō)明。接著說(shuō)selectImports方法,我們來(lái)看一下自動(dòng)配置類(lèi)的加載過(guò)程,AutoConfigurationImportSelector對(duì)于該方法的具體實(shí)現(xiàn)為

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

isEnabled方法是一個(gè)開(kāi)關(guān),用于控制是否啟用自動(dòng)配置,邏輯很簡(jiǎn)單,略過(guò)不提,往下看,關(guān)鍵邏輯在getAutoConfigurationEntry方法中,跟下去

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
        configurations = removeDuplicates(configurations);
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        configurations = getConfigurationClassFilter().filter(configurations);
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }

很容易看到加載邏輯在getCandidateConfigurations方法中,后續(xù)代碼是去重和過(guò)濾的過(guò)程,再往下看

    protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
                getBeanClassLoader());
        Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
                + "are using a custom packaging, make sure that file is correct.");
        return configurations;
    }

這個(gè)方法就很簡(jiǎn)單明顯了,直接調(diào)用SpringFactoriesLoader去加載對(duì)應(yīng)的內(nèi)容,接下來(lái)我們?cè)倭牧腟pringFactoriesLoader機(jī)制是怎么回事。

SpringFactoriesLoader機(jī)制

SpringFactoriesLoader直譯過(guò)來(lái)就是工廠加載機(jī)制,是Spring仿照J(rèn)ava的SPI機(jī)制實(shí)現(xiàn)的一套類(lèi)加載機(jī)制,通過(guò)讀取模塊內(nèi)的META-INF/spring.factories文件來(lái)加載類(lèi),該文件為Properties格式,其中key部分是一個(gè)Class全限定名稱(chēng),可以是一個(gè)接口、抽象類(lèi)或者注解等,而value部分是一個(gè)支持逗號(hào)分割的實(shí)現(xiàn)類(lèi)列表,比如

而SpringFactoriesLoader就是Spring提供的一個(gè)用于讀取解析META-INF/spring.factories文件的工具類(lèi),通過(guò)傳入一個(gè)Class類(lèi)型加載其對(duì)應(yīng)的實(shí)現(xiàn)類(lèi)列表。

SpringFactoriesLoader如何應(yīng)用在自動(dòng)配置中

介紹完了SpringFactoriesLoader,我們來(lái)研究一下SpringBoot的自動(dòng)配置機(jī)制中是怎么使用它的,回到上面的getCandidateConfigurations方法中,我們看一下這一行

List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
                getBeanClassLoader());

其中第一個(gè)參數(shù)是key對(duì)應(yīng)Class類(lèi)型,第二個(gè)參數(shù)是用哪個(gè)ClassLoader去加載配置文件,我們看一下getSpringFactoriesLoaderFactoryClass這個(gè)方法返回的具體Class是什么

    protected Class<?> getSpringFactoriesLoaderFactoryClass() {
        return EnableAutoConfiguration.class;
    }

很簡(jiǎn)單,直接返回@EnableAutoConfiguration注解對(duì)應(yīng)的class類(lèi)型,那么自動(dòng)配置類(lèi)在META-INF/spring.factories文件中的配置方式就顯而易見(jiàn)了,上面截圖中最前面的部分

# AutoConfiguration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration,\
org.springframework.cloud.autoconfigure.LifecycleMvcEndpointAutoConfiguration,\
org.springframework.cloud.autoconfigure.RefreshAutoConfiguration,\
org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration,\
org.springframework.cloud.autoconfigure.WritableEnvironmentEndpointAutoConfiguration

就是對(duì)應(yīng)的自動(dòng)配置類(lèi)了。這些被配置在此處的類(lèi)都會(huì)被作為自動(dòng)配置類(lèi)加載到Spring中,然后進(jìn)行相應(yīng)的處理,發(fā)揮出每個(gè)類(lèi)的功能作用。

小結(jié)

SpringBoot的自動(dòng)配置機(jī)制就簡(jiǎn)單介紹到這里了,相信看官們看完了之后也都有了一些了解,當(dāng)然這篇文章里還有很多相關(guān)內(nèi)容沒(méi)有涉及到,包括自動(dòng)配置類(lèi)的條件加載方式、多個(gè)類(lèi)之間的加載順序控制、排除和過(guò)濾機(jī)制,以及如何自定義自動(dòng)配置類(lèi)、重寫(xiě)框架默認(rèn)行為等等,這些內(nèi)容筆者會(huì)在后續(xù)的文章中再進(jìn)行詳細(xì)探討。

到此這篇關(guān)于SpringBoot原理之自動(dòng)配置機(jī)制的文章就介紹到這了,更多相關(guān)SpringBoot自動(dòng)配置機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java壓縮之LZW算法字典壓縮與解壓講解

    Java壓縮之LZW算法字典壓縮與解壓講解

    今天小編就為大家分享一篇關(guān)于Java壓縮之LZW算法字典壓縮與解壓講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-02-02
  • 高價(jià)值Java多線程面試題分析

    高價(jià)值Java多線程面試題分析

    Java?給多線程編程提供了內(nèi)置的支持。一條線程指的是進(jìn)程中一個(gè)單一順序的控制流,一個(gè)進(jìn)程中可以并發(fā)多個(gè)線程,每條線程并行執(zhí)行不同的任務(wù)。多線程是多任務(wù)的一種特別的形式,但多線程使用了更小的資源開(kāi)銷(xiāo)
    2022-03-03
  • Mybatis實(shí)現(xiàn)動(dòng)態(tài)SQL編寫(xiě)的示例詳解

    Mybatis實(shí)現(xiàn)動(dòng)態(tài)SQL編寫(xiě)的示例詳解

    這篇文章主要為大家詳細(xì)介紹了mybatis中的動(dòng)態(tài)sql的使用以及緩存的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,需要的可以參考一下
    2023-02-02
  • Java8時(shí)間接口LocalDateTime詳細(xì)用法

    Java8時(shí)間接口LocalDateTime詳細(xì)用法

    最近看別人項(xiàng)目源碼,發(fā)現(xiàn)Java8新的日期時(shí)間API很方便強(qiáng)大,所以整理了這篇文章,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有很好的幫助,需要的朋友可以參考下
    2021-05-05
  • Java之操作Redis案例講解

    Java之操作Redis案例講解

    這篇文章主要介紹了Java之操作Redis案例講解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • 解決mybatis分頁(yè)插件PageHelper導(dǎo)致自定義攔截器失效

    解決mybatis分頁(yè)插件PageHelper導(dǎo)致自定義攔截器失效

    這篇文章主要為大家介紹了解決mybatis分頁(yè)插件PageHelper導(dǎo)致自定義攔截器失效方案示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Spring boot JPA實(shí)現(xiàn)分頁(yè)和枚舉轉(zhuǎn)換代碼示例

    Spring boot JPA實(shí)現(xiàn)分頁(yè)和枚舉轉(zhuǎn)換代碼示例

    這篇文章主要介紹了Spring boot JPA實(shí)現(xiàn)分頁(yè)和枚舉轉(zhuǎn)換代碼示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • JS求多個(gè)數(shù)組的重復(fù)數(shù)據(jù)

    JS求多個(gè)數(shù)組的重復(fù)數(shù)據(jù)

    這篇文章主要介紹了JS求多個(gè)數(shù)組的重復(fù)數(shù)據(jù)的辦法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • JavaWeb開(kāi)發(fā)之使用jQuery與Ajax實(shí)現(xiàn)動(dòng)態(tài)聯(lián)級(jí)菜單效果

    JavaWeb開(kāi)發(fā)之使用jQuery與Ajax實(shí)現(xiàn)動(dòng)態(tài)聯(lián)級(jí)菜單效果

    這篇文章主要介紹了JavaWeb開(kāi)發(fā)之使用jQuery與Ajax實(shí)現(xiàn)動(dòng)態(tài)聯(lián)級(jí)菜單效果的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-10-10
  • IDEA中的打包Build Artifacts圖文詳解

    IDEA中的打包Build Artifacts圖文詳解

    當(dāng)項(xiàng)目開(kāi)發(fā)完畢,需要對(duì)外發(fā)布時(shí),我們就會(huì)用到IDEABuild Artifacts功能,那么如果在idea中打包呢,這篇文章主要介紹了IDEA中的打包Build Artifacts詳解,需要的朋友可以參考下
    2024-03-03

最新評(píng)論

大洼县| 龙南县| 浮山县| 明溪县| 万年县| 平陆县| 东兴市| 屯门区| 大兴区| 湖南省| 遂宁市| 阿坝县| 麻阳| 吉首市| 荥经县| 贵州省| 龙陵县| 辽源市| 沧源| 女性| 元阳县| 措美县| 庆阳市| 化州市| 瑞金市| 新乡县| 滨海县| 页游| 夹江县| 葫芦岛市| 昭苏县| 平湖市| 南丰县| 冕宁县| 阿拉善左旗| 芷江| 梁平县| 九寨沟县| 定南县| 大冶市| 丽水市|