Spring Boot 以「約定優於配置」重新定義了 Spring 應用開發體驗。其核心魔法在於 @EnableAutoConfiguration 註解,透過類路徑掃描、條件裝配、屬性綁定三大機制,實現「引入依賴即可用」的零配置啟動。本文將從源碼層面剖析自動配置的完整鏈路,並提供最佳實踐指南。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({ EnableAutoConfigurationImportSelector.class, AutoConfigurationPackages.Registrar.class })
public @interface EnableAutoConfiguration {
Class<?>[] exclude() default {};
}
關鍵在 @Import(EnableAutoConfigurationImportSelector.class),啟動選擇器鏈路。
EnableAutoConfigurationImportSelector 使用 SpringFactoriesLoader.loadFactoryNames() 掃描類路徑下所有 JAR 的 META-INF/spring.factories,查找鍵 org.springframework.boot.autoconfigure.EnableAutoConfiguration 對應的值列表。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\
...(共 100+ 配置類)
每個配置類負責一個垂直領域(資料庫、MQ、Web、安全、模板引擎等)的 Bean 裝配。
自動配置類大量使用 @Conditional 衍生註解,實現「有特定類/Bean/屬性/資源時才生效」:
| 註解 | 條件判斷 | 典型用例 |
|---|---|---|
| @ConditionalOnClass | 類路徑存在指定類 | MongoDB 驅動存在才裝配 MongoTemplate |
| @ConditionalOnMissingClass | 類路徑不存在指定類 | 無 Servlet API 時不裝配 Web 配置 |
| @ConditionalOnBean | 容器已有指定 Bean | 有 DataSource 才裝配 TransactionManager |
| @ConditionalOnMissingBean | 容器無指定 Bean | 用戶未自定義時提供預設 Bean |
| @ConditionalOnProperty | 配置屬性滿足條件 | spring.jpa.enabled=true 才裝配 JPA |
| @ConditionalOnExpression | SpEL 表達式為 true | 複雜組合條件 |
| @ConditionalOnWebApplication | 是 Web 應用 | DispatcherServlet 只在 Web 環境裝配 |
| @ConditionalOnResource | 類路徑存在資源檔 | 存在 schema.sql 才初始化資料庫 |
@Configuration
@ConditionalOnClass(Mongo.class) // 1. 有 Mongo 驅動
@EnableConfigurationProperties(MongoProperties.class) // 2. 綁定屬性前綴 spring.data.mongodb
public class MongoAutoConfiguration {
@Autowired private MongoProperties properties;
private Mongo mongo;
@PreDestroy public void close() { if (mongo != null) mongo.close(); }
@Bean
@ConditionalOnMissingBean // 3. 用戶未自定義 Mongo Bean
public Mongo mongo() throws UnknownHostException {
this.mongo = this.properties.createMongoClient();
return this.mongo;
}
}
三重保障:有驅動、有屬性、用戶未覆蓋,才自動創建 MongoClient Bean。
@ConfigurationProperties(prefix = "spring.data.mongodb")
public class MongoProperties {
private String host;
private int port = 27017;
private String uri = "mongodb://localhost/test";
private String database;
// getters/setters
}
spring.data.mongodb.host=localhost 自動映射到 host 欄位,支援巢狀物件、集合、Duration、DataSize 等豐富類型轉換。強烈建議自定義配置均採用此模式,消除 @Value("${...}") 散落程式碼的痛點。
spring.factories 另一定義 ApplicationContextInitializer:
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer
啟動時註冊監聽器,上下文刷新或啟動失敗時輸出自動配置報告。啟用除錯模式(--debug 或 debug=true)可看到完整匹配/不匹配分析:
Positive matches:
-----------------
DataSourceAutoConfiguration
- @ConditionalOnClass classes found: javax.sql.DataSource, org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType (OnClassCondition)
- @ConditionalOnMissingBean (types: DataSource; SearchStrategy: all) found no beans (OnBeanCondition)
Negative matches:
-----------------
MongoAutoConfiguration
- required @ConditionalOnClass classes not found: com.mongodb.Mongo (OnClassCondition)
SecurityAutoConfiguration
- required @ConditionalOnClass classes not found: org.springframework.security.authentication.AuthenticationManager (OnClassCondition)
報告清晰揭示每個配置類生效/失效的具體條件,是排查「為何我的 Bean 沒裝配」的終極利器。
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class) 或 spring.autoconfigure.exclude 屬性。@Configuration 類中,@ConditionalOnMissingBean 讓自動配置自動退讓。application.yml、環境變數、命令列參數按優先級覆蓋預設值。META-INF/spring.factories 發佈自己的 XxxAutoConfiguration,打包為 Starter 供團隊復用。深入理解自動配置原理,不僅能排查啟動異常、Bean 衝突、屬性不生效等疑難雜症,更能設計出符合 Spring Boot 風格的企業級 Starter,將通用基礎設施(資料源、快取、監控、鏈路追蹤、安全)封裝為「引入即用」的模組,極大提升團隊交付效率。