它們在本質功能上都是為了向 Spring 容器注冊 Bean,但在觸發方式、加載時機、可控性和適用場景上有明顯區別。可以這樣理解:
1?? 核心區別
對比維度 | @Configuration + @Bean (手工配置) | Spring Boot @EnableAutoConfiguration / 自動配置類 |
---|---|---|
觸發方式 | 你顯式編寫配置類并在項目中引入 | Spring Boot 啟動時通過 spring.factories / META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 自動掃描加載 |
加載時機 | 只要配置類被掃描到,就會立即生效 | 通過條件注解(@ConditionalOnClass 、@ConditionalOnMissingBean 等)按需加載 |
可控性 | 完全由你決定加載哪些 Bean | 框架先提供默認 Bean,你可以通過排除或覆蓋來調整 |
靈活性 | 靈活度高,但需要自己寫全部配置 | 開箱即用,減少樣板代碼,但靈活度取決于條件注解設計 |
適用場景 | 項目特定邏輯、強定制化需求 | 常用中間件、通用功能的默認配置(如 DataSource、WebMvc、Jackson 等) |
2?? 工作機制差異
手工配置
@Configuration
public class MyConfig {@Beanpublic MyService myService() {return new MyServiceImpl();}
}
- 優點:可讀性強、可控性高,明確知道 Bean 從哪里來。
- 缺點:重復勞動多,尤其是常用組件的初始化。
自動配置
@Configuration
@ConditionalOnClass(MyService.class)
@ConditionalOnMissingBean
public class MyServiceAutoConfiguration {@Beanpublic MyService myService() {return new MyServiceImpl();}
}
- 優點:只要類路徑存在依賴且你沒自己定義 Bean,就會自動注入,減少配置量。
- 缺點:加載邏輯“隱形”,需要看源碼或文檔才能完全理解。
3?? 本質理解
- 相同點:最終都是注冊 Bean 到 Spring 容器。
- 不同點:
- 手工配置是顯式聲明,你寫什么就加載什么。
- 自動配置是條件驅動,Spring Boot 根據環境和依賴自動幫你注冊默認 Bean,你只需在必要時覆蓋或禁用。
💡 經驗建議:
- 業務核心邏輯 → 用手工
@Configuration
,保證可控性和可讀性。 - 通用基礎設施(數據庫、緩存、消息隊列等) → 借助自動配置,減少樣板代碼。
- 如果默認自動配置不符合需求,可以用:
或者直接自己定義同名 Bean 覆蓋。@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})