1. Spring Boot 自动配置原理?(必考,讲清楚)

入口:@SpringBootApplication = @SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan。

自动配置的核心链路:

  1. @EnableAutoConfiguration 上标注了 @Import(AutoConfigurationImportSelector.class)
  2. AutoConfigurationImportSelector 扫描所有 jar 中的 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(Spring Boot 2.7+,旧版是 spring.factories)
  3. 加载到候选自动配置类(如 DataSourceAutoConfiguration、RedisAutoConfiguration、MybatisAutoConfiguration 等一百多个)
  4. 对每个候选类执行条件注解过滤(@ConditionalOnClass、@ConditionalOnMissingBean 等),只有条件满足的才会注册 BeanDefinition
  5. 同时结合 @EnableConfigurationProperties 把 application.yml 中的 spring.datasource.* 等前缀属性绑定到 @ConfigurationProperties 类,注入自动配置 Bean
最小化理解:自动配置 = 条件判断 + 属性绑定
@AutoConfiguration                          // 声明这是自动配置类(2.7+ 注解)
@ConditionalOnClass(DataSource.class)       // 类路径有 DataSource 才生效
@EnableConfigurationProperties(DataSourceProperties.class)  // 绑定配置项
class DataSourceAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean               // 用户自定义了 DataSource 就不创建
    public DataSource dataSource(DataSourceProperties p) {
        return p.initializeDataSourceBuilder().build();
    }
}

🎯 面试要点

  • 条件注解是自动配置的"开关":核心 6 个 @ConditionalOnClass/@ConditionalOnMissingClass、@ConditionalOnBean/@ConditionalOnMissingBean、@ConditionalOnProperty、@ConditionalOnWebApplication
  • @ConditionalOnMissingBean 保证了"用户自定义优先"——你配了自己的 Bean,自动配置的就不生效
  • 调试利器:启动加 --debug 看 Auto Configuration Report(哪些条件没满足及原因)

2. starter 是什么?如何自定义 starter?

starter:一个"装好依赖 + 自动配置"的 jar 包。引入 spring-boot-starter-data-redis 就自动拥有 Redis 连接和操作能力——约定优于配置的体现。

自定义 starter 的步骤:

  1. 创建 autoconfigure 模块:@AutoConfiguration 类 + 条件注解 + @ConfigurationProperties
  2. 在 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 中注册自动配置类全限定名
  3. 创建 starter 模块:只放依赖(引 autoconfigure + 业务所需依赖),POM 依赖即可
  4. 使用者引入 starter,配置 yml 属性即可生效

🎯 面试要点

  • starter 通常拆两个模块:xxx-spring-boot-starter(依赖聚合) + xxx-spring-boot-autoconfigure(逻辑)
  • 内部 starter:spring-boot-starter-*(官方)、mybatis-spring-boot-starter(第三方)
  • 识别生效:启动日志 "ConditionEvaluationReportLoggingListener" 或 debug 模式

3. SpringApplication.run() 的启动流程?

  1. 准备阶段:推断应用类型(Servlet/Reactive)、加载 spring.factories 中的初始化器 ApplicationContextInitializer、准备监听器 ApplicationListener
  2. 解析 main 类(找到 @SpringBootApplication)
  3. 创建 Environment:加载 application.yml/properties,绑定系统属性、命令行参数(优先级:命令行 > 环境变量 > yml)
  4. 创建并刷新容器:createApplicationContext → prepareContext(后置处理器、监听器触发)→ refreshContext(调用 Spring 的 refresh() 全流程)
  5. 启动完成阶段:调用 ApplicationRunner/CommandLineRunner(业务启动后逻辑),发布 ApplicationReadyEvent
启动后执行逻辑的三种方式
// 1. ApplicationRunner(推荐,参数已解析)
@Component
class StartupRunner implements ApplicationRunner {
    @Override public void run(ApplicationArguments args) { ... }
}

// 2. CommandLineRunner(原始字符串参数)
class CmdRunner implements CommandLineRunner {
    @Override public void run(String... args) { ... }
}

// 3. 监听 ApplicationReadyEvent(更底层)
@EventListener(ApplicationReadyEvent.class)
void onReady() { ... }

🎯 面试要点

  • ApplicationRunner 在容器 refresh 完成后执行(Bean 都可用),适合初始化数据/预热缓存
  • 多个 Runner 用 @Order 排序
  • 配置优先级(低到高):yml → 系统环境变量 → Java 系统属性 → 命令行参数(--server.port=8081)

4. 配置文件与 profile 机制?

@ConfigurationProperties 绑定
# application.yml
app:
  name: order-service
  thread:
    core-size: 8
    max-size: 16

@Component
@ConfigurationProperties(prefix = "app")
@Data  // Lombok
class AppProperties {
    private String name;
    private final Thread thread = new Thread();
    @Data static class Thread { private int coreSize; private int maxSize; }
}
// 用法:@Autowired AppProperties(自动绑定 + 启动时校验类型)

🎯 面试要点

  • @ConfigurationProperties 开启方式:@EnableConfigurationProperties 或 @ConfigurationPropertiesScan
  • 配置中心(Nacos/Config)能动态刷新:配合 @RefreshScope 重新创建 Bean
  • 敏感信息用环境变量注入而非写死在 yml

🎤 常见面试追问

  1. 自动配置的核心链路(背下来)?——@SpringBootApplication 里的 @EnableAutoConfiguration → @Import(AutoConfigurationImportSelector) → 扫描所有 jar 的 AutoConfiguration.imports → 条件注解过滤 → 只注册条件满足的配置类 → 属性绑定到 @ConfigurationProperties。
  2. @ConditionalOnMissingBean 起什么作用?——用户自定义了同类型 Bean 时自动配置不生效(用户优先)。这就是"为什么我配了自己的 DataSource 后自动配置就不创建了"。
  3. 配置文件优先级?——命令行参数 > Java 系统属性 > 环境变量 > application.yml(高优先覆盖低优先)。
  4. @ConfigurationProperties 和 @Value 的区别?——@ConfigurationProperties 整组绑定到对象(强类型、可校验、推荐);@Value 单个取。多配置项用前者。
  5. 启动后执行代码有几种方式?——ApplicationRunner / CommandLineRunner(推荐,容器刷新后执行,@Order 排序);监听 ApplicationReadyEvent。

📖 名词解释(本页术语)

术语 大白话解释
Spring Boot简化 Spring 开发的框架:自动配置 + starter 依赖 + 内嵌服务器,一个 main 方法启动整个应用。
自动配置根据 classpath 和配置自动装配 Bean(有 Redis 依赖就自动配 RedisTemplate),"约定优于配置"的体现。
条件注解@ConditionalOnXxx 系列:满足条件才注册 Bean(如 @ConditionalOnClass 依赖存在才生效)——自动配置的"开关"。
starter"装好依赖 + 自动配置"的起步依赖包,如 spring-boot-starter-data-redis。
@ConfigurationProperties把 yml 配置按前缀绑定到 POJO 对象(app.xxx → AppProperties)。
Profile环境配置:application-dev.yml / application-prod.yml,用 spring.profiles.active 切换。
ApplicationRunner应用启动完成后执行的回调接口(初始化数据、预热缓存放这里)。
⚠️ 本页面由 AI 生成,内容仅供参考,请以官方文档和实际源码为准。