Spring Boot 核心原理与面试高频考点
涵盖 Spring Boot 自动配置、启动流程、Starter 设计、外部化配置、Web 容器切换、Actuator 安全、异步任务、内存泄漏、多数据源、3.x 迁移、代理机制、启动优化、优雅停机、初始化器、循环依赖、健康检查、分布式事务、K8s 探针、JSON 序列化及 Jakarta EE 兼容性等 20 个核心面试题,解析底层原理与最佳实践。

涵盖 Spring Boot 自动配置、启动流程、Starter 设计、外部化配置、Web 容器切换、Actuator 安全、异步任务、内存泄漏、多数据源、3.x 迁移、代理机制、启动优化、优雅停机、初始化器、循环依赖、健康检查、分布式事务、K8s 探针、JSON 序列化及 Jakarta EE 兼容性等 20 个核心面试题,解析底层原理与最佳实践。

答案:
Spring Boot 自动配置的核心流程如下:
考察点: SPI 机制、条件装配、启动流程、扩展点设计。
答案:
Web 应用关键步骤如下:
考察点: 启动生命周期、上下文刷新、内嵌容器集成、事件机制。
答案:
Starter 结构:
设计原则:
@ConditionalOnClass(MyService.class)
@ConditionalOnMissingBean(MyService.class)
// 允许用户覆盖
@Configuration
public class MyServiceAutoConfiguration {
@Bean
public MyService myService() {
return new MyService();
}
}
@ConfigurationProperties("my.service")
public class MyServiceProperties {
/* ... */
}
并在自动配置类中注入。 4. 注册到 spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports:
com.example.MyServiceAutoConfiguration
避免冲突:
考察点: 模块化设计、开闭原则、配置优先级。
答案:
加载优先级(高→低):
动态刷新配置:
@EventListener
public void onEnvironmentChange(EnvironmentChangeEvent event) {
if (event.getKeys().contains("my.config.key")) {
// 手动更新内部状态
}
}
注意:普通 @ConfigurationProperties Bean 不会自动刷新,需配合 @RefreshScope。
考察点: 配置管理、生产运维、云原生适配。
答案:
可插拔机制:
切换方式:
<!-- 排除 Tomcat -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 引入 Undertow -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
考察点: SPI 设计、依赖管理。
答案:
安全控制:
management:
endpoints:
web:
exposure:
include: health,metrics,env
endpoint:
health:
show-details: always
@Configuration
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests()
.anyRequest().hasRole("ACTUATOR").and().httpBasic();
}
}
自定义健康检查:
@Component
public class CustomHealthIndicator implements HealthIndicator {
@Override
public Health health() {
boolean isOk = checkExternalService();
if (isOk) {
return Health.up().withDetail("service", "available").build();
} else {
return Health.down().withDetail("reason", "timeout").build();
}
}
}
考察点: 生产安全、可观测性、扩展能力。
答案:
正确使用 @Async:
自定义线程池(避免使用默认 SimpleAsyncTaskExecutor):
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean("taskExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("async-task-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
异常处理:
考察点: AOP 代理机制、线程池调优、异常治理。
答案:
常见原因:
排查工具:
优化建议:
考察点: JVM 调优、生产问题定位、资源管理。
答案:
静态多数据源:
动态数据源(基于 AOP):
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DS {
String value();
}
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.get(); // ThreadLocal 存储
}
}
@Aspect
@Component
public class DataSourceAspect {
@Before("@annotation(ds)")
public void switchDS(DS ds) {
DataSourceContextHolder.set(ds.value());
}
@After("@annotation(ds)")
public void restoreDS() {
DataSourceContextHolder.clear();
}
}
@Bean
@Primary
public DataSource dynamicDataSource() {
DynamicDataSource ds = new DynamicDataSource();
ds.setTargetDataSources(Map.of("master", masterDS, "slave", slaveDS));
ds.setDefaultTargetDataSource(masterDS);
return ds;
}
考察点: AOP、数据源抽象、线程上下文传递。
答案:
主要变化:
考察点: 技术演进、云原生。
答案:
示例:
@Configuration
public class AppConfig {
@Bean
public ServiceA serviceA() {
return new ServiceA();
}
@Bean
public ServiceB serviceB() {
return new ServiceB(serviceA()); // 调用本类的 serviceA()
}
}
考察点: Spring 容器生命周期、代理机制、配置类语义保障。
答案:
常见原因:
诊断工具:
logging.level.org.springframework.boot.StartupInfoLogger=DEBUG
management:
metrics:
enable: true
tags:
application: ${spring.application.name}
查看 /actuator/metrics/startup.*。 3. 使用 Async Profiler 或 JFR (Java Flight Recorder) 分析 CPU/锁/IO。
优化手段:
spring.main.lazy-initialization=true
考察点: 性能工程、可观测性、启动优化策略。
答案:
启用方式(Spring Boot 2.3+):
server:
shutdown: graceful
spring:
lifecycle:
timeout-per-shutdown-phase: 30s
内部机制:
注意事项(陷阱):
考察点: 云原生运维、服务治理、生命周期管理。
答案:
典型场景:
考察点: 扩展点时机、初始化逻辑分层、安全敏感操作位置。
答案:
Spring Boot 并未改变 Spring Framework 的循环依赖处理机制,依然依赖三级缓存:
Spring Boot 中的注意事项:
考察点: IoC 容器原理、设计反模式识别、代码质量意识。
答案:
实现'部分失败仍 UP':
@Component
public class CustomHealthAggregator implements HealthAggregator {
@Override
public Health aggregate(Map<String, Health> healths) {
Status status = Status.UP;
// 例如:只有核心服务 DOWN 才整体 DOWN
if (isCoreServiceDown(healths)) {
status = Status.DOWN;
}
return new Health.Builder(status).withDetails(healths).build();
}
private boolean isCoreServiceDown(Map<String, Health> healths) {
return healths.get("database") != null && healths.get("database").getStatus() == Status.DOWN;
}
}
然后在配置中指定:
management:
endpoint:
health:
show-details: always
health:
defaults:
aggregator: customHealthAggregator
考察点: 可观测性定制、业务健康模型、运维策略落地。
答案:
方案对比:
Spring Boot 集成 Seata 示例:
选型建议:
考察点: 分布式系统设计、CAP 权衡、落地经验。
答案:
Liveness Probe(存活探针):
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 60
periodSeconds: 30
failureThreshold: 3
不要包含外部依赖(如 DB 连接),否则网络抖动导致误杀。
Readiness Probe(就绪探针):
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 1
可包含 DB、Redis 等关键依赖检查。
Spring Boot 2.3+ 内置支持:
考察点: 云原生运维、弹性伸缩、服务网格集成。
答案:
问题场景:
解决方案:
public class Views {
public static class Public {}
public static class Internal extends Public {}
}
public class User {
@JsonView(Views.Public.class)
private String name;
@JsonView(Views.Internal.class)
private String password;
}
Controller 中指定:
@JsonView(Views.Public.class)
@GetMapping("/user")
public User getUser() {...}
全局配置:
@Configuration
public class JacksonConfig {
@Bean
public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() {
return new Jackson2ObjectMapperBuilder()
.failOnEmptyBeans(false)
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
}
}
考察点: 安全编码、API 设计、序列化控制。
答案:
主要变化:
兼容性问题:
平滑升级策略:
考察点: 技术债务管理、大版本迁移、生态兼容性评估。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online