Skip to content

自动配置原理

  自动配置是 Spring Boot 最核心的特性,也是最常被问到的面试题。它让 Spring Boot 能根据 classpath 中的依赖自动配置 Bean,开发者几乎零配置启动项目。

一、自动配置的入口

java
@SpringBootApplication
// ↓ 这个注解开启了自动配置
@EnableAutoConfiguration
// ↓ 导入了自动配置选择器
@Import(AutoConfigurationImportSelector.class)
public class Application { }
自动配置的触发链路:

  @SpringBootApplication
    → @EnableAutoConfiguration
      → @Import(AutoConfigurationImportSelector.class)
        → selectImports()
          → getAutoConfigurationEntry()
            → getCandidateConfigurations()
              → 读取 spring.factories / .imports 文件
                → 加载所有自动配置类
                  → 条件注解过滤
                    → 最终生效的配置

二、自动配置类的加载

Spring Boot 2.x(spring.factories):

  META-INF/spring.factories:
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
    org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
    ...

Spring Boot 3.x(.imports 文件,推荐):

  META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports:
    org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
    org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
    ...

三、条件注解

  条件注解是自动配置的核心筛选机制,决定某个自动配置类是否生效。

条件注解作用示例
@ConditionalOnClassclasspath 中存在指定类有 DataSource 类
@ConditionalOnMissingClassclasspath 中不存在指定类没有 H2 类
@ConditionalOnBean容器中存在指定 Bean有 DataSource Bean
@ConditionalOnMissingBean容器中不存在指定 Bean用户没自定义 DataSource
@ConditionalOnProperty配置文件中存在指定属性spring.datasource.url 有值
@ConditionalOnResourceclasspath 中存在指定资源mybatis-config.xml
@ConditionalOnWebApplication是 Web 应用
@ConditionalOnExpressionSpEL 表达式为 true

四、DataSource 自动配置实战解析

java
// 简化版 DataSourceAutoConfiguration 源码
@AutoConfiguration
@ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class})  // ① 有 DataSource 类
@EnableConfigurationProperties(DataSourceProperties.class)            // ② 绑定配置属性
@Import({DataSourcePoolMetadataProvidersConfiguration.class, ...})
public class DataSourceAutoConfiguration {

    @Configuration
    @ConditionalOnMissingBean(DataSource.class)  // ③ 用户没自定义 DataSource
    static class EmbeddedDatabaseConfiguration {
        // ④ 创建嵌入式数据库(H2)
    }

    @Configuration
    @Conditional(PooledDataSourceCondition.class)  // ③ 连接池条件
    static class PooledDataSourceConfiguration {
        // ④ 创建连接池 DataSource(HikariCP)
        @Bean
        @ConfigurationProperties(prefix = "spring.datasource.hikari")
        DataSource dataSource(DataSourceProperties properties) {
            HikariDataSource dataSource = properties.initializeDataSourceBuilder()
                    .type(HikariDataSource.class).build();
            return dataSource;
        }
    }
}
DataSource 自动配置决策流程:

  ① 检查 classpath 是否有 DataSource 类
    ├─ 没有 → 不配置
    └─ 有 → 继续

  ② 检查容器中是否已有 DataSource Bean
    ├─ 有(用户自定义了) → 使用用户的
    └─ 没有 → 继续

  ③ 检查 spring.datasource.url 是否有值
    ├─ 有 → 创建连接池 DataSource(HikariCP)
    └─ 没有 → 创建嵌入式数据库(H2)

五、自定义自动配置

java
// 第一步:创建配置属性类
@ConfigurationProperties(prefix = "my.ratelimit")
@Data
public class RateLimitProperties {
    private boolean enabled = true;
    private int maxRequests = 100;
    private int windowSeconds = 60;
}

// 第二步:创建自动配置类
@AutoConfiguration
@ConditionalOnClass(RateLimiter.class)
@EnableConfigurationProperties(RateLimitProperties.class)
public class RateLimitAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "my.ratelimit", name = "enabled",
                           havingValue = "true", matchIfMissing = true)
    public RateLimiter rateLimiter(RateLimitProperties properties) {
        return new RateLimiter(properties.getMaxRequests(), properties.getWindowSeconds());
    }
}

// 第三步:注册自动配置类
// 在 resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
// 添加:com.mycompany.autoconfigure.RateLimitAutoConfiguration

六、条件注解执行顺序

自动配置的执行顺序由 @AutoConfigureBefore / @AutoConfigureAfter 控制:

  @AutoConfiguration
  @AutoConfigureAfter(DataSourceAutoConfiguration.class)   // 在 DataSource 配置后执行
  @AutoConfigureBefore(JdbcTemplateAutoConfiguration.class) // 在 JdbcTemplate 配置前执行
  public class MyAutoConfiguration { }

七、面试要点

Q1:自动配置的原理是什么?

  @EnableAutoConfiguration → @Import(AutoConfigurationImportSelector) → 从 .imports 文件加载所有自动配置类 → 通过条件注解(@ConditionalOnClass、@ConditionalOnMissingBean 等)筛选 → 符合条件的自动配置生效。

Q2:如何自定义一个 starter?

  创建自动配置类 → 使用 @ConfigurationProperties 绑定配置 → 通过条件注解控制生效条件 → 在 .imports 文件中注册 → 打包发布。

Q3:Spring Boot 有哪些条件注解?

  @ConditionalOnClass、@ConditionalOnMissingClass、@ConditionalOnBean、@ConditionalOnMissingBean、@ConditionalOnProperty、@ConditionalOnResource、@ConditionalOnWebApplication、@ConditionalOnExpression。