spring boot autoconfigure 自动配置的类,和手工 @configuration + @bean 本质区别
它们在本质功能上都是为了向 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})