自动配置是Spring Boot的关键特性之一,它简化了传统Spring应用繁琐的配置,通过智能推断和条件化配置简化了Spring应用的开发。
1. 自动配置的核心思想
目标:根据项目的依赖(如类路径中的 JAR 包)和已有的配置,自动创建和配置 Spring Bean,避免手动编写 XML 或 Java 配置。
关键特点:
-
条件化配置(@Conditional):根据条件(如类是否存在、Bean 是否缺失等)决定是否启用配置。
-
默认优先:提供合理的默认值,同时允许开发者覆盖配置。
-
模块化 :通过
starter
依赖按需引入配置。
2. 自动配置的核心原理
(1)核心注解:@SpringBootApplication
- @SpringBootApplication 注解组合了**@Configuation(标记为配置类)、@ComponentScan(包扫描)、@EnableAutoConfiguration(启用自动配置)**。
- 作用:启用自动配置,扫描 META-INF/spring.factories文件,加载其中定义的自动配置类。
- 关键点:@EnableAutoConfiguration 是激活自动配置的入口。
(2)自动配置类注册:xxx.imports
-
文件路径: META-INF/xxx.imports (位于spring-boot-autoconfigure JAR包)
-
-
内容: 键为 **org.springframework.boot.autoconfigure.EnableAutoConfiguration ,**值为多个自动配置类的全限定名。
-
示例:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
(3)条件注解(Conditional Annotations)
SpringBoot使用条件注解控制配置类的生效条件:
- @ConditionalOnClass:类路径中存在指定类时生效
- @ConditionalOnMissingBean:容器中不存在指定 Bean 时生效
- @ConditionalOnProperty:配置文件中存在指定属性时生效
- @ConditionalOnWebApplication:当前应用是Web应用时生效
示例(DataSourceAutoConfiguration
):
java
@Configuration
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@EnableConfigurationProperties(DataSourceProperties.class)
public class DataSourceAutoConfiguration {
// 当容器中没有 DataSource Bean 时,自动配置嵌入式数据库
@Bean
@ConditionalOnMissingBean
public DataSource dataSource() {
// 创建默认的 DataSource(如 H2、HikariCP)
}
}
(4)配置属性绑定:@EnableConfigurationProperties
- 通过 application.properties 或 application.yml文件中的属性动态配置Bean。
3. 自动配置的执行流程
-
启动应用 :调用
SpringApplication.run(),初始化应用上下文。
-
加载自动配置类:
- 扫描所有
META-INF/xxx.imports
文件,获取EnableAutoConfiguration
对应的配置类列表。
- 扫描所有
-
过滤配置类:
- 根据条件注解(如
@ConditionalOnClass
)排除不满足条件的配置类。(如缺少依赖,Bean已存在等)。
- 根据条件注解(如
-
应用配置(注册Bean):
- 将符合条件的配置类加载到Spring容器,创建所需的Bean。
4. 自动配置示例:Web MVC
当引入 spring-boot-starter-web
依赖时:
-
依赖触发 :类路径中存在
Servlet
、Spring MVC
相关类。 -
自动配置生效:
-
WebMvcAutoConfiguration
自动配置DispatcherServlet
、视图解析器等。 -
默认静态资源路径(
/static
,/public
)生效。
-
-
自定义覆盖:
- 开发者可通过
@Bean
自定义ViewResolver
覆盖默认配置。
- 开发者可通过
5.自定义自动配置
-
覆盖默认配置:
-
定义自己的 Bean:Spring Boot 优先使用用户定义的 Bean(
@ConditionalOnMissingBean
会失效)。java@Bean public DataSource myDataSource() { // 自定义 DataSource,覆盖自动配置 }
-
-
创建自定义starter:
-
创建自动配置类:
java@Configuration @ConditionalOnClass(MyService.class) public class MyServiceAutoConfiguration { @Bean public MyService myService() { return new MyService(); } }
-
注册配置类到
META-INF/xxx.imports
:javaorg.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.MyServiceAutoConfiguration
-
总结:SpringBoot自动配置原理
- 在主启动类上添加了SpringBootApplication注解,这个注解组合了EnableAutoConfiguration注解
- EnableAutoConfiguration注解又组合了Import注解,导入了AutoConfigurationImportSelector类
- 实现selectImports方法,这个方法经过层层调用,最终会读取META-INF目录下的后缀名为imports的文件,boot 2.7以前的版本读取的是spring.factories文件
- 读取到全类名之后,会解析注册条件,也就是@Conditional及其衍生注解,把满足注册条件的Bean对象自动注入到IOC容器中