前言

Spring Boot 面试题通常不会只问“它和 Spring 有什么区别”。更常见的问题是:自动配置怎么生效,Starter 做了什么,@SpringBootApplication 包含哪些能力,Bean 生命周期如何走,配置文件加载顺序是什么,事务为什么会失效,接口请求进入后经历哪些链路,线上启动慢或接口慢怎么排查。

如果只把 Spring Boot 理解成“简化 Spring 配置的框架”,回答很容易停留在使用层。更好的方式是把它理解成一条完整链路:

1
启动应用 -> 创建 SpringApplication -> 准备 Environment -> 加载自动配置 -> 创建 Bean -> 启动 Web 容器 -> 接收请求 -> 执行业务和事务

本文按面试中最常见的模块梳理 Spring Boot 要点,适合作为面试前的复习清单。

Spring Boot 整体定位

Spring Boot 是基于 Spring 生态的应用开发框架,核心目标是降低 Spring 应用的配置成本,让开发者更快构建可运行、可部署、可监控的服务。

它主要解决三个问题:

  • 自动配置:根据依赖和条件自动装配常用组件。
  • 起步依赖:通过 Starter 管理一组相关依赖。
  • 生产可用:提供内嵌容器、配置体系、Actuator、日志和外部化配置能力。

面试中可以这样概括:

Spring Boot 不是替代 Spring,而是在 Spring 之上提供自动配置、依赖约定和生产化能力。它让应用从“手动配置大量 Bean”变成“按约定引入依赖并覆盖少量配置”。

@SpringBootApplication

@SpringBootApplication 是 Spring Boot 启动类上最常见的注解,它是组合注解,核心包含:

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan
1
2
3
4
5
6
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}

含义如下:

  • @SpringBootConfiguration:标记这是一个配置类,本质上包含 @Configuration
  • @EnableAutoConfiguration:开启自动配置。
  • @ComponentScan:扫描启动类所在包及其子包下的组件。

常见问题:为什么有些 Bean 扫描不到?

通常是启动类包路径放得太深,导致 @ComponentScan 默认扫描范围没有覆盖目标类。解决方式是调整启动类位置或显式配置扫描包。

自动配置原理

自动配置是 Spring Boot 面试核心。

简化流程如下:

flowchart TD
    A[启动应用] --> B[@EnableAutoConfiguration]
    B --> C[读取 AutoConfiguration.imports]
    C --> D[加载自动配置类]
    D --> E[@Conditional 条件判断]
    E --> F[满足条件则注册 Bean]

Spring Boot 会根据类路径依赖、配置项、已有 Bean、运行环境等条件,决定是否注册某些默认 Bean。

常见条件注解:

  • @ConditionalOnClass:类路径存在某个类时生效。
  • @ConditionalOnMissingBean:容器中没有某个 Bean 时生效。
  • @ConditionalOnProperty:配置项满足条件时生效。
  • @ConditionalOnBean:容器中存在某个 Bean 时生效。
  • @ConditionalOnWebApplication:Web 应用环境下生效。

面试中可以这样回答:

自动配置不是无条件创建所有 Bean,而是先读取自动配置类,再通过一组 Conditional 条件判断是否装配。开发者自定义 Bean 通常会优先于默认 Bean,因为很多自动配置使用 @ConditionalOnMissingBean

Starter

Starter 是一组依赖和自动配置的组合入口。

例如引入:

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

通常会带来:

  • Spring MVC
  • Jackson
  • Validation
  • 内嵌 Tomcat
  • Web 相关自动配置

Starter 的价值:

  • 降低依赖管理成本。
  • 减少版本冲突。
  • 按场景聚合依赖。
  • 配合自动配置做到开箱即用。

自定义 Starter 通常包括两部分:

  • starter 模块:提供依赖聚合。
  • autoconfigure 模块:提供自动配置类和属性配置类。

SpringApplication 启动流程

Spring Boot 启动流程可以概括为:

1
创建 SpringApplication -> 推断应用类型 -> 加载初始化器和监听器 -> 准备 Environment -> 创建 ApplicationContext -> 刷新容器 -> 启动 WebServer -> 执行 Runner

更细一点:

  1. 创建 SpringApplication
  2. 推断是普通应用、Servlet Web 应用还是 Reactive Web 应用。
  3. 加载 ApplicationContextInitializer 和监听器。
  4. 准备环境变量、命令行参数和配置文件。
  5. 创建 ApplicationContext
  6. 加载 BeanDefinition。
  7. 执行容器刷新,创建单例 Bean。
  8. 启动内嵌 Web 容器。
  9. 执行 CommandLineRunnerApplicationRunner

面试不一定要背完整源码方法名,但要能讲清楚:环境准备、上下文创建、Bean 装配、Web 容器启动、启动后回调。

Bean 生命周期

Spring Boot 的 Bean 生命周期本质上还是 Spring Bean 生命周期。

常见流程:

1
实例化 -> 属性填充 -> Aware 回调 -> BeanPostProcessor 前置处理 -> 初始化 -> BeanPostProcessor 后置处理 -> 使用 -> 销毁

常见扩展点:

  • 构造方法
  • @PostConstruct
  • InitializingBean#afterPropertiesSet
  • 自定义 initMethod
  • BeanPostProcessor
  • @PreDestroy
  • DisposableBean#destroy
  • 自定义 destroyMethod

BeanPostProcessor 很重要,AOP、事务、异步等很多能力都依赖后置处理器为 Bean 创建代理。

配置加载

Spring Boot 支持外部化配置,常见配置来源包括:

  • 命令行参数。
  • Java 系统属性。
  • 环境变量。
  • application.ymlapplication.properties
  • profile 配置,例如 application-prod.yml
  • 配置中心。

常见读取方式:

1
2
@Value("${app.name}")
private String appName;
1
2
3
4
@ConfigurationProperties(prefix = "app")
public class AppProperties {
private String name;
}

复杂配置更推荐 @ConfigurationProperties,因为它支持类型安全绑定、嵌套对象、集合和校验。

面试常问 profile:

1
2
3
spring:
profiles:
active: prod

启动时也可以通过参数指定:

1
java -jar app.jar --spring.profiles.active=prod

Web 请求链路

Spring Boot Web 应用通常使用 Spring MVC。一个请求进入后,大致链路如下:

sequenceDiagram
    participant Client
    participant Filter
    participant DispatcherServlet
    participant Interceptor
    participant Controller
    participant Service
    participant DB

    Client->>Filter: HTTP Request
    Filter->>DispatcherServlet: 过滤后转发
    DispatcherServlet->>Interceptor: preHandle
    Interceptor->>Controller: 调用 Handler
    Controller->>Service: 执行业务
    Service->>DB: 数据访问
    DB-->>Service: 返回数据
    Service-->>Controller: 返回结果
    Controller-->>DispatcherServlet: ResponseBody
    DispatcherServlet-->>Client: HTTP Response

核心组件:

  • Filter:Servlet 过滤器,作用在 DispatcherServlet 前后。
  • DispatcherServlet:Spring MVC 前端控制器。
  • HandlerMapping:查找请求对应的 Controller 方法。
  • HandlerAdapter:执行 Controller 方法。
  • Interceptor:Spring MVC 拦截器。
  • HttpMessageConverter:请求体和响应体转换。
  • ControllerAdvice:统一异常处理和响应增强。

Filter 更靠近 Servlet 容器,Interceptor 更靠近 Spring MVC。

事务

Spring 事务常见通过 @Transactional 实现,本质是 AOP 代理。

事务失效常见原因:

  • 同类内部方法调用,绕过代理。
  • 方法不是 public。
  • 异常被捕获后没有抛出。
  • 默认只对 RuntimeException 和 Error 回滚。
  • 数据库引擎不支持事务。
  • 多线程异步执行脱离原事务上下文。
  • 注解加在未被 Spring 管理的对象上。

示例:

1
2
3
4
5
@Transactional(rollbackFor = Exception.class)
public void createOrder() {
// 保存订单
// 扣减库存
}

面试中要强调:@Transactional 不是魔法,它依赖 Spring AOP 代理和数据库事务能力。

异常处理

Spring Boot 常见统一异常处理方式是 @RestControllerAdvice + @ExceptionHandler

1
2
3
4
5
6
7
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
public ApiResult<?> handleBusiness(BusinessException ex) {
return ApiResult.fail(ex.getMessage());
}
}

好处:

  • Controller 不需要重复 try-catch。
  • 错误响应格式统一。
  • 业务异常和系统异常分层处理。
  • 便于记录日志和告警。

常见建议:

  • 业务异常返回明确错误码。
  • 系统异常不要直接暴露堆栈。
  • 参数校验异常统一转换。
  • 关键异常保留 traceId,方便排查。

参数校验

Spring Boot 常用 Bean Validation 做参数校验。

1
2
3
4
5
6
7
public class CreateUserRequest {
@NotBlank
private String username;

@NotNull
private Integer age;
}

Controller 中使用:

1
2
3
4
@PostMapping("/users")
public ApiResult<?> create(@Valid @RequestBody CreateUserRequest request) {
return ApiResult.ok();
}

常见注解:

  • @NotNull
  • @NotBlank
  • @NotEmpty
  • @Min
  • @Max
  • @Size
  • @Pattern

参数校验应该放在入口层,复杂业务规则再放到 Service 层。

Actuator

Spring Boot Actuator 提供生产监控端点。

常见端点:

  • /actuator/health
  • /actuator/metrics
  • /actuator/prometheus
  • /actuator/info
  • /actuator/env
  • /actuator/beans
  • /actuator/threaddump

常见用途:

  • 健康检查。
  • 指标采集。
  • 线程排查。
  • Bean 和配置检查。
  • 与 Prometheus、Grafana 等监控系统集成。

注意:生产环境不要无保护暴露敏感端点,例如 envbeansheapdump,应配置权限和网络访问控制。

日志和链路追踪

Spring Boot 默认使用 Logback,也可以切换 Log4j2 等日志框架。

常见日志实践:

  • 区分 info、warn、error。
  • 关键链路打印业务 ID。
  • 接入 traceId。
  • 避免日志中输出敏感信息。
  • 控制大对象和循环日志。
  • 异常日志保留堆栈。

线上排查时,traceId、请求 ID、用户 ID、订单 ID 等上下文比单纯错误信息更重要。

常见性能优化

启动优化:

  • 减少不必要 Starter。
  • 控制组件扫描范围。
  • 延迟初始化非关键 Bean。
  • 检查启动 Runner 中的慢操作。
  • 避免启动时同步加载大量数据。

接口优化:

  • 数据库查询加索引。
  • 避免循环调用远程接口。
  • 使用连接池并设置合理超时。
  • 慢任务异步化。
  • 返回字段按需裁剪。
  • 合理使用缓存。

资源优化:

  • 配置合理线程池。
  • 配置数据库连接池大小。
  • 监控 JVM、GC、线程和连接池。
  • 配置接口超时和熔断降级。

常见排查思路

如果面试官问“Spring Boot 应用启动慢怎么排查”,可以按以下路径回答:

  1. 看启动日志中耗时最长的阶段。
  2. 看是否引入过多 Starter 或自动配置。
  3. 看组件扫描范围是否过大。
  4. 看 Bean 初始化是否执行远程调用或大量数据加载。
  5. CommandLineRunnerApplicationRunner 是否有慢任务。
  6. 看数据库连接、配置中心、注册中心是否连接慢。
  7. 使用 Actuator 或启动分析工具查看 Bean 加载情况。

如果接口突然变慢,可以按以下路径回答:

  1. 看是单接口慢还是全站慢。
  2. 看请求日志和 traceId。
  3. 看 Controller、Service、DAO 各阶段耗时。
  4. 看数据库慢 SQL、索引和连接池。
  5. 看远程调用超时和重试。
  6. 看线程池、Tomcat 线程、队列和拒绝数。
  7. 看 JVM GC、CPU、内存和锁等待。

高频面试题

Spring Boot 和 Spring 有什么区别?

Spring 是基础框架,提供 IoC、AOP、事务、MVC 等能力;Spring Boot 基于 Spring,提供自动配置、Starter、内嵌容器、外部化配置和 Actuator,让应用更容易启动、开发和部署。

自动配置怎么实现?

Spring Boot 通过 @EnableAutoConfiguration 加载自动配置类,再通过 @ConditionalOnClass@ConditionalOnMissingBean@ConditionalOnProperty 等条件判断是否注册 Bean。

Starter 是什么?

Starter 是按场景聚合的一组依赖,通常配合自动配置使用。引入 Starter 后,相关依赖和默认配置会自动生效,开发者只需要覆盖必要配置。

为什么自定义 Bean 能覆盖默认配置?

很多自动配置类使用 @ConditionalOnMissingBean。如果用户已经定义了同类型 Bean,默认 Bean 就不会再创建。

@Transactional 为什么会失效?

常见原因包括同类内部调用、方法不是 public、异常被捕获、默认不回滚 checked exception、对象不是 Spring Bean、多线程异步执行、数据库不支持事务等。

Filter 和 Interceptor 有什么区别?

Filter 属于 Servlet 规范,执行在 DispatcherServlet 前后;Interceptor 属于 Spring MVC,执行在 Handler 调用前后。Filter 更底层,Interceptor 更容易拿到 Spring MVC 上下文。

Actuator 有什么用?

Actuator 提供健康检查、指标、线程、环境、Bean 等生产监控能力,常用于服务探活、监控采集和问题排查。生产环境要注意端点权限和敏感信息保护。

总结

Spring Boot 面试的主线可以围绕四个问题展开:

  1. 应用怎么启动:SpringApplication、Environment、ApplicationContext、WebServer。
  2. Bean 怎么装配:自动配置、Starter、Conditional、Bean 生命周期。
  3. 请求怎么处理:Filter、DispatcherServlet、Interceptor、Controller、MessageConverter。
  4. 线上怎么治理:事务失效、异常处理、Actuator、日志、性能优化和排查。

把这条链路讲清楚,再结合自动配置原理、事务失效场景和生产排查思路,Spring Boot 相关问题就能从“会用框架”升级成“理解框架运行机制”。