国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

詳解 Spring Boot 自動配置原理和應用

開發 前端
我們詳細闡述了 Spring Boot 自動配置機制的實現原理,從源碼角度分析了為什么 Spring Boot 能夠做到自動配置,并結合 MyBatis 框架分析了它在開源框架中的具體應用。

我們知道,基于 Spring Boot,開發人員只需要在類路徑中引入一組第三方框架的 starter 組件,就能在 Spring 容器中使用這些框架所提供的各項功能。這在當下的開發過程中已是常態,但在 Spring Boot 還沒有誕生之前卻是不可想象的。如果我們使用傳統的 Spring 框架,那就需要添加各種繁雜的配置信息才能啟動容器。那么,Spring Boot 是通過什么樣的機制來做到這一點的呢?這就是今天我們要討論的內容——Spring Boot 的自動配置機制。

可以說,Spring Boot 的自動配置機制應用非常廣泛。在目前主流的開源框架中,都提供了各自的 starter 組件。例如,MyBatis 的 starter 組件為 mybatis-spring-boot-starter。而從擴展性上講,這也是 Spring Boot 為開發人員提供的一整套擴展機制,我們可以基于這套擴展機制實現自定義的 starter 組件。

Spring Boot 自動配置機制原理

Spring Boot 的自動配置功能非常強大,但也有一定的復雜度,讓我們先來深入理解其背后的實現原理。

@EnableAutoConfiguration 注解

我們通過查看@SpringBootApplication 注解的定義,發現該注解實際上是一個復合注解,由@SpringBootConfiguration、@ComponentScan 和@EnableAutoConfiguration 這三個獨立注解所組成。

圖 1 @SpringBootApplication 注解的組成結構圖 1 @SpringBootApplication 注解的組成結構

我們知道@ComponentScan 是傳統 Spring 框架中對內置的注解,而@SpringBootConfiguration 注解也很簡單,實際上只是對 Spring 框架中另一個常用注解@Configuration 的一種包裝,本身沒有定義任何內容。所以,我們接下來重點剖析@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 {};
}

可以看到,這里出現了一個新的注解,即@AutoConfigurationPackage。從命名上講, @AutoConfigurationPackage 注解的作用就是自動對某一個代碼包進行配置。

另一方面,我們還看到這里通過@Import 注解引入了一個 AutoConfigurationImportSelector 類。從命名上,我們也不難理解該類的作用是完成對導入的配置信息的自動選擇。AutoConfigurationImportSelector 類的核心方法 getCandidateConfigurations 實現了這一目標。

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
       List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
       …
       return configurations;
}

這里引出了在 Spring Boot 中真正負責加載配置信息的 SpringFactoriesLoader 類。這些類之間的交互關系如圖 2 所示:

圖 2 AutoConfigurationImportSelector 類層結構圖圖 2 AutoConfigurationImportSelector 類層結構圖

顯然,想要完成配置信息的自動選擇,我們首先需要執行配置文件的加載操作,這部分功能是由 SpringFactoriesLoader 來完成的。SpringFactoriesLoader 也是 Spring Boot 自動配置得以實現的關鍵組件,我們來一起看一下。

SpringFactoriesLoader

SpringFactoriesLoader 類似 JDK 實現 SPI 機制時所使用的 ServiceLoader 類,區別只是配置文件的存放位置和配置項對應的鍵值定義不同。在 SpringFactoriesLoader 中,我們需要通過 META-INF/spring.factories 文件目錄,來獲取服務定義文件,并通過 EnableAutoConfiguration 這個配置鍵來獲取具體的配置信息。圖 3 展示了 SpringFactoriesLoader 和 ServiceLoader 之間的區別。

圖 3 SpringFactoriesLoader 和 ServiceLoader 區別示意圖圖 3 SpringFactoriesLoader 和 ServiceLoader 區別示意圖

圖 3 SpringFactoriesLoader 和 ServiceLoader 區別示意圖

SpringFactoriesLoader 基于圖 3 指定的配置文件名和配置鍵獲取對應的配置信息,然后基于這些配置信息來實例化配置類,這里 Spring Boot 用到的是反射機制。SpringFactoriesLoader 類中的 loadSpringFactories 方法展示了這一過程。

private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
       //從緩存中獲取配置內容,如果存在則直接返回
       try {
              //基于 ClassLoader 從 META-INF/spring.factories 獲取配置文件資源地址 URL
              while (urls.hasMoreElements()) {
                     //獲取配置文件資源,加載配置項
                     for (Map.Entry<?, ?> entry : properties.entrySet()) {
                     //組裝配置項 Key-Value
                     }
              }
              //把配置信息放入緩存
              //返回結果
       }
}

同時,我們在 spring-boot-autoconfigure 工程的 spring.factories 配置文件中找到了如下所示配置項。

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoCnotallow=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
…

可以看到,EnableAutoConfiguration 配置項中,定義了各種以-AutoConfiguration 結尾的配置類。通過 SpringFactoriesLoader,Spring Boot 就能做到在服務啟動的時候把它們加載到容器中并實現自動化配置。

MyBatis Spring Boot Starter

介紹完 Spring Boot 中應用程序的自動配置機制之后,我們來做一些實踐,通過剖析 MyBatis Spring Boot Starter 的啟動過程來加深對內容的理解。

在 mybatis-spring-boot-starter 中存在幾個代碼工程,我們重點關注 mybatis-spring-boot-autoconfigure 工程。而在這個代碼工程中,最重要的顯然就是 MybatisAutoConfiguration 類。對于 Spring Boot 中的 AutoConfiguration 類,我們首先需要重點關注的是類定義上的注解。

@org.springframework.context.annotation.Configuration
@ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class })
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties(MybatisProperties.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class MybatisAutoConfiguration implements InitializingBean {

我們看到這里用到了@ConditionalOnClass 和@ConditionalOnSingleCandidate 這兩個注解,它們就是 Spring Boot 中的條件注解。在介紹 MybatisAutoConfiguration 之前,有必要對這些注解做一定展開。

@ConditionalOn 系列條件注解

我們在前面的內容中已經了解到以-AutoConfiguration 結尾的自動配置類數量會很多,在一個應用程序的開發過程中,我們通常不會全部用到它們。這時候就需要引入一種機制來對這些自動配置類進行過濾。為此,Spring Boot 提供了一組@ConditionalOn 系列條件注解。通過這些注解,我們就可以基于特定的條件有選擇性地加載某些配置類。在 Spring Boot 中常見的條件注解可以參考圖 4。

圖 4 常見@ConditionalOn 系列注解及其作用圖 4 常見@ConditionalOn 系列注解及其作用

在前面介紹的 MybatisAutoConfiguration 類的時候,出現了@ConditionalOnClass 和@ConditionalOnSingleCandidate 這兩個條件注解。基于這兩個條件注解,我們可以明確 MybatisAutoConfiguration 能夠實例化的前提有兩個:一是類路徑中存在 SqlSessionFactory 和 SqlSessionFactoryBean;另一個則是容器中只存在一個 DataSource 實例。兩者缺一不可,這是一種常用的自動配置控制技巧。

然后,我們在 MybatisAutoConfiguration 類上看到了一個@EnableConfigurationProperties 注解。通過這個注解,所有添加了@ConfigurationProperties 注解的配置類就會自動生效。這里的@EnableConfigurationProperties 注解中指定的是 MybatisProperties 類,該類定義了 MyBatis 運行時所需要的各種配置信息,而我們在 MybatisProperties 類上確實也發現了@ConfigurationProperties 注解,并設置了 prefix 為“mybatis”。

@ConfigurationProperties(
     prefix = "mybatis"
)
public class MybatisProperties {
       ...
}

最后,在 MybatisAutoConfiguration 類上還存在一個@AutoConfigureAfter 注解,這個注解可以根據字面意思進行理解,即在完成某一個類的自動配置之后再執行當前類的自動配置。這個需要提前裝配的類指的就是 DataSourceAutoConfiguration。

MybatisAutoConfiguration

理解了@ConditionalOnXXX、@EnableConfigurationProperties 和@AutoConfigureAfter 等一系列注解之后,我們回過頭來再看 MybatisAutoConfiguration 類的代碼結構就顯得比較簡單了。MybatisAutoConfiguration 類中的一個核心方法就是如下所示的 sqlSessionFactory 方法。

@Bean
@ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
    SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
    factory.setDataSource(dataSource);
    factory.setVfs(SpringBootVFS.class);
    if (StringUtils.hasText(this.properties.getConfigLocation())) {
      factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
    }
    applyConfiguration(factory);
    //省略一系列配置項設置方法
    return factory.getObject();
}

顯然,這里基于前面介紹的 SqlSessionFactoryBean 構建了 SqlSessionFactory 實例。注意到在該方法上同樣添加了一個@ConditionalOnMissingBean 注解,標明只有在當前上下文中不存在 SqlSessionFactoryBean 對象時才會執行上述方法。

同樣,添加了@ConditionalOnMissingBean 注解的,還有如下所示的 sqlSessionTemplate 方法。

@Bean
@ConditionalOnMissingBean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
    ExecutorType executorType = this.properties.getExecutorType();
    if (executorType != null) {
      return new SqlSessionTemplate(sqlSessionFactory, executorType);
    } else {
      return new SqlSessionTemplate(sqlSessionFactory);
    }
}

該方法用于構建一個 SqlSessionTemplate 對象實例。在 MyBatis 中,SqlSessionTemplate 實現了 SqlSession 接口,相當于是全局唯一的 SqlSession 實例。

接下來,我們需要在 META-INF/spring.factories 文件中明確所指定的自動配置類。根據 Spring Boot 自動配置機制的原理,對于 mybatis-spring-boot-autoconfigure 工程而言,這個配置項內容應該如下所示。

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoCnotallow=\
org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration

至此,整個 MyBatis Spring Boot Starter 的介紹就告一段落。作為總結,我們可以把創建一個 Spring Boot Starter 的過程抽象成三個步驟。

圖 5 創建 Spring Boot Starter 的三個步驟圖 5 創建 Spring Boot Starter 的三個步驟

在日常開發過程中,我們就可以基于這三大步驟來實現一個自定義的 Spring Boot Starter。

總結

今天,我們詳細闡述了 Spring Boot 自動配置機制的實現原理,從源碼角度分析了為什么 Spring Boot 能夠做到自動配置,并結合 MyBatis 框架分析了它在開源框架中的具體應用。同時,我們在本講結尾部分還總結了開發一個 Spring Boot Starter 的三大步驟。實現一個自定義 Spring Boot Starter 也是日常開發的常見需求,我們在開發過程中可以基于本講的內容加深對其實現原理的理解。

最后,我想給你留一道思考題:你能簡要描述實現一個自定義 Spring Boot Starter 需要哪些開發步驟嗎?

責任編輯:武曉燕 來源: 程序猿技術充電站
相關推薦

2023-10-18 08:12:34

Spring自動配置

2021-08-06 08:04:14

Spring Boot自動配置

2024-12-25 16:01:01

2017-03-23 09:29:06

2021-02-11 08:08:09

Spring Boot配置架構

2025-07-08 07:15:00

Spring配置多種方式

2024-01-04 08:16:34

Spring國際化標準

2025-03-25 10:00:00

Spring開發Java

2023-12-27 18:05:13

2024-12-16 08:10:00

Spring開發

2017-04-26 11:00:34

Spring BootHelloWorld詳解

2024-04-23 14:13:38

開發配置文件

2019-09-03 15:36:58

ApacheTomcat配置

2020-07-08 13:46:27

ApacheTomcat配置

2017-09-20 09:46:38

Spring BootSpring Clou內存

2025-02-28 08:14:53

2020-11-02 07:00:29

Spring Boo注解自動化

2025-02-13 07:45:26

APISpringHTTP

2025-05-29 05:59:56

2017-06-26 08:47:05

Spring Boot自動化配置
點贊
收藏

51CTO技術棧公眾號

精品一区二区不卡| 精品99999| 蜜臀av一区二区在线免费观看| 2020最新国产精品| 伦xxxx在线| 天天干夜夜干| 国产日产欧美视频| 欧美日韩综合网| 国产精品一区二区久久国产| 激情欧美亚洲| 日本19禁啪啪吃奶大尺度| 亚洲欧洲精品一区二区| 国产精品欧美亚洲777777| 久久视频在线播放| 日韩成人在线免费观看| 欧美亚洲一区二区在线观看| 亚洲人成精品久久久久久| 国产精品综合在线视频| 蜜桃av一区| 国产一区二区三区自拍| 欧美影院三区| 亚洲超碰在线观看| 国产精品亚洲d| 国产在线看片免费视频在线观看| 一本一道波多野毛片中文在线| av超碰在线观看| 美丽的小蜜桃4春潮| 国产三级视频| 国产福利在线免费| 欧美亚洲另类在线一区二区三区| 国产精品揄拍一区二区| 欧美一乱一性一交一视频| 欧美激情高清视频| 欧美日韩xxxxx| 久久乐国产精品| 香蕉成人在线| 成人av免费在线看| 亚洲香蕉伊综合在人在线视看| 在线观看亚洲精品视频| 久久久久久久电影| 国产午夜一区二区三区| 国产一区999| 国产麻豆精品一区二区| 精品影院一区二区久久久| 老鸭窝亚洲一区二区三区| 美女尤物国产一区| 成人综合激情网| 亚洲国产成人午夜在线一区| 国产最新精品免费| 成人av在线资源网站| 久久先锋影音av鲁色资源网| 国产日韩精品一区二区三区 | 456成人影院在线观看| www.欧美| 99精品在线| 蜜桃一区二区三区在线| 久久影视一区二区| 亚洲一区二区三区在线| 欧美性xxxxxx少妇| 亚洲欧美日韩综合| 日本一区二区不卡| 久久精精品视频| 99999精品视频| 免费h片在线| 国产理论在线| 久久丁香四色| 中文字幕一区二区精品区| 麻豆国产91在线播放| 国产日韩欧美综合一区| 欧美最猛黑人xxxxx猛交| 亚洲免费视频网站| 国产精品一区二区三区在线| 国产黄色片大全| 中文字幕在线资源 | 欧美老女人xx| 国产精品久久婷婷六月丁香| 日韩亚洲欧美视频| 三级视频网站在线| 色8久久久久| 国产精品中文字幕欧美| 国产日韩欧美制服另类| 精品对白一区国产伦| 久久久久久久影院| 国产精品99久久久久久久| 国产精品12p| 成人a在线视频免费观看| 涩涩涩久久久成人精品 | 国产成人av| 麻豆精品视频在线观看免费 | 国产91在线|亚洲| 91精品国产色综合久久久蜜香臀| 国产精品都在这里| 午夜视频在线瓜伦| 亚洲伊人伊成久久人综合网| 亚洲东热激情| 欧美日韩在线一区| 日本久久91av| 友田真希在线| 日韩电影二区| 色视频一区二区| 精品婷婷色一区二区三区蜜桃| 97国产在线| av中文一区| 亚洲一区二区综合| 亚洲影视九九影院在线观看| 国语对白在线视频| 爱情电影社保片一区| 国产精品综合视频| 久久久999精品视频| 青青青青草视频| 激情久久一区二区| 免费国产亚洲视频| 亚洲精品狠狠操| 免费日韩在线观看| 麻豆理论在线观看| 精品一区二区三区视频| 亚洲精品理论电影| 91免费国产精品| 欧美成年网站| 一区在线中文字幕| 国产精品综合久久久久久| 国模私拍视频在线播放| 99久久久免费精品国产一区二区| 欧美精品videossex性护士| 传媒在线观看| 国产精品入口| 美女视频黄免费的亚洲男人天堂| 天天操天天爱天天爽| 在线成人直播| 日韩精品中文字| 久久久久久77777| 噜噜噜在线观看免费视频日韩| 中文字幕日韩av综合精品| 五月综合网站| 久久精品日产第一区二区 | 亚洲成人国产精品| 男女av免费观看| 狠狠色综合网| 性欧美亚洲xxxx乳在线观看| 搞黄视频免费在线观看| 美腿丝袜亚洲三区| 久久久亚洲精品视频| 蜜桃av在线免费观看| 国产精品超碰97尤物18| 999国产视频| 伊人www22综合色| 亚洲缚视频在线观看| 奇米影视888狠狠狠777不卡| 成人高清免费观看| 国产精品一区二区三区www| 亚洲在线一区二区三区| 强开小嫩苞一区二区三区网站 | 亚洲精品菠萝久久久久久久| 亚洲精品一区二区三区av| 亚洲v天堂v手机在线| 久久久国产精品免费| 国产在线一区二区视频| 国产精品久久久久影院亚瑟| 伊人久久大香线蕉综合75| 国产精品一区二区三区av| 亚洲国产精品va在线看黑人| 在线视频中文字幕久| 91毛片在线观看| 天堂一区二区三区| 午夜久久免费观看| 欧美激情亚洲综合一区| 男人的天堂免费在线视频| 69久久夜色精品国产69蝌蚪网| 日韩写真福利视频在线| 亚洲欧美国产77777| 2025韩国理伦片在线观看| 26uuu国产电影一区二区| 少妇一晚三次一区二区三区| 国产伦精品一区二区三区在线观看| 国产精品精品软件视频| 不卡一区综合视频| 国产在线日韩在线| 日韩毛片视频| 国产精品老牛影院在线观看| 电影中文字幕一区二区| 久久精品视频在线播放| www一区二区三区| 欧美成人猛片aaaaaaa| 超碰在线caoporen| 精品少妇一区二区三区| 色呦呦在线看| 亚洲日韩中文字幕| 久久9999免费视频| 色综合天天综合网国产成人网| 爱搞国产精品| 精品久久久久久最新网址| 蜜桃麻豆av在线| www.欧美免费| 精品国产18久久久久久洗澡| 国产91精品视频在线观看| 精品国产第一国产综合精品| 国产精品久久综合av爱欲tv| 伊人成人网在线看| 视频一区二区三| 国产成人精品综合在线观看 |