一文徹底弄懂spring boot自動轉配的過程

lgx211發表於2024-10-27

Spring Boot 的自動配置機制是它的重要特性之一,極大地簡化了 Spring 應用的配置工作。自動配置的核心思想是基於類路徑中的依賴、環境配置以及自定義程式碼進行智慧化配置,避免了開發者手動編寫大量的樣板程式碼。

接下來,我將詳細介紹 Spring Boot 自動配置的過程,核心原理以及涉及的關鍵元件,並結合原始碼進行深入解析。

一、Spring Boot 自動配置的工作流程

  1. @SpringBootApplication 註解
    自動配置的起點通常是 @SpringBootApplication 註解,它是一個組合註解,包含了三個重要註解:

    • @SpringBootConfiguration:標記為一個 Spring 配置類,類似於 @Configuration
    • @EnableAutoConfiguration:啟用 Spring Boot 的自動配置機制。
    • @ComponentScan:掃描當前包及其子包下的所有 Spring 元件。

    其中 @EnableAutoConfiguration 是自動配置的核心,它引導自動配置機制。

  2. @EnableAutoConfigurationAutoConfigurationImportSelector
    @EnableAutoConfiguration 註解的作用是告訴 Spring Boot 啟動時自動配置 Spring 應用上下文。該註解引入了 AutoConfigurationImportSelector,這是自動配置的核心處理器。

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @AutoConfigurationPackage
    @Import(AutoConfigurationImportSelector.class)
    public @interface EnableAutoConfiguration {
    }
    

    AutoConfigurationImportSelector 類會從配置檔案中(通常是 spring.factories)讀取所有的自動配置類,並將它們匯入到應用上下文中。

  3. spring.factories 檔案
    自動配置類是透過 spring-boot-autoconfigure 模組的 META-INF/spring.factories 檔案來配置的。這個檔案中列出了所有可以被自動載入的配置類:

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
    org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
    org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
    ...
    

    這些配置類會在 Spring Boot 啟動時根據當前環境條件被選擇性載入。

  4. 條件裝配(@Conditional 系列註解)
    Spring Boot 並不是盲目地載入所有的自動配置類。每個自動配置類通常都會使用 @Conditional 系列註解來進行有條件的載入。最常見的條件註解有:

    • @ConditionalOnClass:當類路徑中存在某個類時才生效。
    • @ConditionalOnMissingBean:當 Spring 上下文中不存在某個 Bean 時才生效。
    • @ConditionalOnProperty:當某個配置屬性滿足特定條件時才生效。
    • @ConditionalOnBean:當 Spring 上下文中存在某個 Bean 時才生效。

    例如,DataSourceAutoConfiguration 只有在專案中存在資料來源相關的依賴(如 javax.sql.DataSource 類)時才會被載入。

  5. 自動配置類示例:DataSourceAutoConfiguration

    Spring Boot 中 DataSourceAutoConfiguration 是配置資料來源的自動配置類,它的原始碼如下:

    @Configuration
    @ConditionalOnClass(DataSource.class)
    @EnableConfigurationProperties(DataSourceProperties.class)
    @Import({DataSourcePoolMetadataProvidersConfiguration.class,
             DataSourceInitializationConfiguration.class})
    public class DataSourceAutoConfiguration {
    
        @Bean
        @ConditionalOnMissingBean
        public DataSource dataSource(DataSourceProperties properties) {
            // 建立並返回 DataSource 物件
            return properties.initializeDataSourceBuilder().build();
        }
    }
    
    • @ConditionalOnClass(DataSource.class):只有當類路徑下存在 DataSource 類時,才進行資料來源的自動配置。
    • @ConditionalOnMissingBean:如果 Spring 上下文中沒有其他 DataSource Bean,則自動配置一個。

    這種基於條件的配置方式確保了 Spring Boot 的靈活性,允許使用者透過覆蓋預設 Bean 或不滿足條件的方式跳過某些自動配置。

二、Spring Boot 自動配置的核心步驟

  1. 收集自動配置類
    啟動時,AutoConfigurationImportSelectorspring.factories 檔案中讀取所有的自動配置類,並透過 @Import 匯入這些類。
  2. 條件檢查
    自動配置類的載入不是無條件的,Spring Boot 會根據 @Conditional 註解進行條件檢查,確保只有符合條件的自動配置類才會生效。
  3. 注入所需的 Bean
    一旦自動配置類透過條件檢查,Spring Boot 就會根據這些配置類註冊所需的 Bean。例如,DataSourceAutoConfiguration 會自動配置資料來源相關的 Bean。
  4. 允許使用者覆蓋自動配置
    自動配置並不是強制的。使用者可以透過顯式宣告自己的 Bean 來覆蓋自動配置的預設行為。例如,如果使用者在自己的配置類中定義了 DataSource,那麼 Spring Boot 就不會再自動配置資料來源。

三、Spring Boot 自動配置的實際案例

  1. Web 應用自動配置
    在 Spring Boot Web 應用中,DispatcherServletAutoConfiguration 負責自動配置 Spring MVC 的核心元件,例如 DispatcherServletRequestMappingHandlerMapping 等。

    • 如果專案中存在 spring-web 依賴,那麼 DispatcherServletAutoConfiguration 會自動載入。
    • 如果沒有手動定義 DispatcherServlet,Spring Boot 會自動建立一個 DispatcherServlet 並配置到 Spring 容器中。
  2. 資料庫連線池自動配置
    Spring Boot 還會自動配置資料庫連線池(如 HikariCP、Tomcat JDBC 等),這依賴於專案中的 spring-boot-starter-data-jpa 或者 spring-boot-starter-jdbc 依賴。

    • DataSourceAutoConfigurationDataSourceProperties 共同負責自動配置資料來源。
    • 如果類路徑中存在連線池類(如 HikariDataSource),那麼 Spring Boot 就會自動配置連線池。

    同時,使用者可以透過 application.properties 檔案來自定義連線池配置:

    spring.datasource.url=jdbc:mysql://localhost:3306/mydb
    spring.datasource.username=root
    spring.datasource.password=secret
    spring.datasource.hikari.maximum-pool-size=10
    
  3. Spring Security 自動配置
    當引入 spring-boot-starter-security 依賴時,Spring Boot 會自動配置安全機制,預設提供 HTTP Basic 認證機制。

    • SecurityAutoConfiguration 負責自動配置 Spring Security 的基礎設施。
    • 如果需要定製安全策略,可以透過自定義 WebSecurityConfigurerAdapter 來覆蓋預設配置。

四、Spring Boot 自動配置的好處

  1. 極大地簡化配置工作:開發者不再需要為每個基礎設施元件編寫配置程式碼,自動配置機制根據專案依賴自動注入所需的 Bean。
  2. 靈活性:自動配置並不會束縛開發者。開發者可以透過自定義配置輕鬆覆蓋預設的自動配置。
  3. 約定優於配置:Spring Boot 遵循 "約定優於配置" 的原則,只需少量的配置,Spring Boot 就能完成複雜的初始化工作。

五、Spring Boot 自動配置與 Spring 自動裝配的區別

  • Spring 自動裝配:指透過 @Autowired 等註解,根據型別自動注入依賴 Bean。它側重於注入已經配置好的 Bean。
  • Spring Boot 自動配置:是根據類路徑中的依賴和環境資訊自動配置 Spring 元件的過程。它負責建立並配置所需的基礎設施 Bean。

總結來說,Spring Boot 的自動配置機制透過 @EnableAutoConfiguration 啟動,基於 spring.factories 中的配置和 @Conditional 條件判斷,自動注入所需的 Bean,簡化了開發者的配置工作,同時保留了靈活的定製能力。

相關文章