🚀 Spring Boot
自动配置原理 · starter 机制 · 条件注解 · SpringApplication 启动流程 · 配置体系
1. Spring Boot 自动配置原理?(必考,讲清楚)
入口:@SpringBootApplication = @SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan。
自动配置的核心链路:
- @EnableAutoConfiguration 上标注了
@Import(AutoConfigurationImportSelector.class) - AutoConfigurationImportSelector 扫描所有 jar 中的
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(Spring Boot 2.7+,旧版是 spring.factories) - 加载到候选自动配置类(如 DataSourceAutoConfiguration、RedisAutoConfiguration、MybatisAutoConfiguration 等一百多个)
- 对每个候选类执行条件注解过滤(@ConditionalOnClass、@ConditionalOnMissingBean 等),只有条件满足的才会注册 BeanDefinition
- 同时结合 @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 的步骤:
- 创建 autoconfigure 模块:@AutoConfiguration 类 + 条件注解 + @ConfigurationProperties
- 在
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports中注册自动配置类全限定名 - 创建 starter 模块:只放依赖(引 autoconfigure + 业务所需依赖),POM 依赖即可
- 使用者引入 starter,配置 yml 属性即可生效
🎯 面试要点
- starter 通常拆两个模块:xxx-spring-boot-starter(依赖聚合) + xxx-spring-boot-autoconfigure(逻辑)
- 内部 starter:spring-boot-starter-*(官方)、mybatis-spring-boot-starter(第三方)
- 识别生效:启动日志 "ConditionEvaluationReportLoggingListener" 或 debug 模式
3. SpringApplication.run() 的启动流程?
- 准备阶段:推断应用类型(Servlet/Reactive)、加载 spring.factories 中的初始化器 ApplicationContextInitializer、准备监听器 ApplicationListener
- 解析 main 类(找到 @SpringBootApplication)
- 创建 Environment:加载 application.yml/properties,绑定系统属性、命令行参数(优先级:命令行 > 环境变量 > yml)
- 创建并刷新容器:createApplicationContext → prepareContext(后置处理器、监听器触发)→ refreshContext(调用 Spring 的 refresh() 全流程)
- 启动完成阶段:调用 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 机制?
- application.yml:主配置;application-{profile}.yml:环境配置(dev/test/prod)
- 激活方式:
spring.profiles.active=prod(yml 中、环境变量 SPRING_PROFILES_ACTIVE、启动参数 --spring.profiles.active=prod) - @ConfigurationProperties:把配置前缀映射到 POJO(强类型、可校验),推荐;@Value 单值注入
- 配置刷新(Spring Cloud Config 场景):@RefreshScope
@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