成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

詳解 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自動配置

2024-12-25 16:01:01

2021-08-06 08:04:14

Spring Boot自動配置

2017-03-23 09:29:06

2021-02-11 08:08:09

Spring Boot配置架構

2025-03-25 10:00:00

Spring開發Java

2024-01-04 08:16:34

Spring國際化標準

2023-12-27 18:05:13

2017-04-26 11:00:34

Spring BootHelloWorld詳解

2024-04-23 14:13:38

開發配置文件

2024-12-16 08:10:00

Spring開發

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

2025-05-29 05:59:56

2020-11-02 07:00:29

Spring Boo注解自動化

2024-11-21 14:42:31

2024-10-14 17:18:27

2025-01-15 08:19:12

SpringBootRedis開源
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品毛片无码 | 精品国产一区二区在线 | 精品视频一区二区三区在线观看 | 青青伊人久久 | 男女羞羞在线观看 | 亚洲国产69 | 国产一级毛片精品完整视频版 | 69性欧美高清影院 | 国产精品久久久久久久久久久久 | 久久精片 | 日本不卡一区 | 国产不卡一区 | 欧美黄色网络 | 四虎影院新地址 | 一区精品国产欧美在线 | 久久com| 综合一区二区三区 | 欧美视频成人 | 日本久草 | 亚洲一页 | 麻豆久久久久久久久久 | av一级久久 | 免费国产视频在线观看 | 国产精品久久久久久婷婷天堂 | 日本视频在线播放 | 日韩成人免费 | 九九热久久免费视频 | 欧日韩不卡在线视频 | 国产乱码久久久久久一区二区 | 精品久久国产 | 亚洲va在线va天堂va狼色在线 | 国产一级毛片视频 | 日韩在线电影 | av第一页| 午夜小视频免费观看 | 亚洲精品免费在线观看 | 国产伦一区二区三区视频 | 麻豆久久久久久久 | 久久国品片 | 久久精品国产亚洲一区二区三区 | 日韩视频一区 |