Spring Boot 自动配置原理,看完终于不慌了

用了两年 Spring Boot,@SpringBootApplication 一加就什么都能用。但一直不知道背后到底发生了什么。直到最近面试被深挖,才认真看了一遍源码。

从一个注解开始

java 复制代码
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

@SpringBootApplication 其实是个组合注解:

java 复制代码
@SpringBootConfiguration      // 就是 @Configuration,标记配置类
@EnableAutoConfiguration      // 核心:开启自动配置
@ComponentScan                // 扫描当前包及子包的 @Component

重点在 @EnableAutoConfiguration。

@EnableAutoConfiguration

java 复制代码
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
}

它通过 @Import 导入了 AutoConfigurationImportSelector,这个类会去读一个文件:

bash 复制代码
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

这个文件里列出了所有自动配置类的全限定名,大概长这样:

erlang 复制代码
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
org.springframework.boot.autoconfigure.redis.RedisAutoConfiguration
org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration
...

Spring Boot 启动的时候,把这些配置类全部加载进来。

以 DataSource 为例

java 复制代码
@AutoConfiguration
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })  // classpath 下有这些类才生效
@EnableConfigurationProperties(DataSourceProperties.class)              // 绑定 application.yml 的配置
public class DataSourceAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean                                           // 用户没自己定义才创建
    public DataSource dataSource(DataSourceProperties properties) {
        return properties.initializeDataSourceBuilder().build();
    }
}

逻辑很清晰:

  1. @ConditionalOnClass:classpath 下有 DataSource 类才激活(你引入了 mysql-connector 就有)
  2. @ConditionalOnMissingBean:如果你自己定义了 DataSource Bean,就不创建了
  3. DataSourceProperties:从 application.yml 里读 spring.datasource.* 配置

所以你只要在 yml 里配了数据库信息,Spring Boot 就自动帮你创建 DataSource。不需要写任何 Java 代码。

条件注解家族

注解 含义
@ConditionalOnClass classpath 有某个类才生效
@ConditionalOnMissingClass classpath 没有某个类才生效
@ConditionalOnBean 容器里有某个 Bean 才生效
@ConditionalOnMissingBean 容器里没有某个 Bean 才创建
@ConditionalOnProperty 配置属性满足条件才生效
@ConditionalOnWebApplication 是 Web 应用才生效

这些条件注解是自动配置的核心------满足条件就生效,不满足就跳过。所以引入一堆 starter 也不会冲突。

自定义自动配置

你也可以写自己的 starter:

java 复制代码
// 1. 定义配置属性
@ConfigurationProperties(prefix = "myservice")
public class MyServiceProperties {
    private String apiKey;
    private int timeout = 5000;
    // getter/setter
}

// 2. 写自动配置类
@AutoConfiguration
@ConditionalOnClass(MyClient.class)
@EnableConfigurationProperties(MyServiceProperties.class)
public class MyServiceAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public MyClient myClient(MyServiceProperties properties) {
        return new MyClient(properties.getApiKey(), properties.getTimeout());
    }
}

// 3. 注册到 imports 文件
// META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.example.MyServiceAutoConfiguration

别人引入你的 starter 依赖后,配一下 myservice.api-key 就能直接用了。

怎么排查自动配置

启动时加参数,看哪些自动配置生效了、哪些被跳过了:

bash 复制代码
java -jar app.jar --debug

或者在 application.yml 里:

yaml 复制代码
debug: true

输出里会有 CONDITIONS EVALUATION REPORT,列出每个配置类的匹配/不匹配条件:

sql 复制代码
Positive matches:
   DataSourceAutoConfiguration matched:
      - @ConditionalOnClass found required classes

Negative matches:
   RedisAutoConfiguration did not match:
      - @ConditionalOnClass did not find required class 'redis.clients.jedis.Jedis'

总结

Spring Boot 自动配置的原理就是:@EnableAutoConfiguration → 读取 imports 文件 → 加载所有配置类 → 每个配置类用条件注解判断是否生效。满足条件就自动创建 Bean,不满足就跳过。你只需要引入 starter + 配 yml,剩下的框架帮你搞定。

相关推荐
丑陋小蚊子2 小时前
有作品集的岗位,简历和作品各写什么?
面试·求职招聘·大学生·简历·简历下载
Ysx2 小时前
踩了 5 次"本地全绿、生产失效"之后,我把交付流程做成了 SOP
后端·程序员
程序员cxuan3 小时前
DeepSeek Harness 出了桌面端?我把它扒了一遍
人工智能·后端·程序员
多多爱学习3 小时前
括号有几层?得看还有多少个左括号没闭合
c语言·c++·算法·面试
丑陋小蚊子3 小时前
同一家公司升过岗,简历别合成一段
面试·求职招聘·大学生·简历·简历下载
Hilaku4 小时前
为什么前端应该主动去学数据库?
前端·javascript·程序员
此时不提桶,更待何时4 小时前
05-04-B-HBase与时序库面试与生产事故实战
数据库·面试·hbase
小酒星小杜6 小时前
画 AI 漫画,别只会写“日漫风”:10 种画风、适用故事和可复制提示词
人工智能·设计模式·程序员
怕浪猫6 小时前
分享一个做视频的skill,这条白板视频,每一笔都是代码画的
前端·javascript·面试