跳到主要内容

Spring Boot 常见面试题

问题

Spring Boot 面试中还有哪些高频问题?

答案

本文汇总 Spring Boot 面试中的其他高频问题,补充已有文档未覆盖的知识点。

Spring Boot 启动流程

启动后执行逻辑

CommandLineRunner & ApplicationRunner
// 方式1:CommandLineRunner(参数是 String[])
@Component
@Order(1) // 控制执行顺序
public class DataInitRunner implements CommandLineRunner {
@Override
public void run(String... args) {
// 应用启动后执行:初始化数据、预热缓存等
}
}

// 方式2:ApplicationRunner(参数是 ApplicationArguments,更结构化)
@Component
@Order(2)
public class CacheWarmRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) {
// args.getOptionValues("name") 可获取 --name=value 参数
}
}

Spring Boot 与 Spring 的区别

对比SpringSpring Boot
配置大量 XML 或 Java Config自动配置 + 约定优于配置
依赖管理手动管理每个依赖版本Starter 统一管理
服务器需要外部 Tomcat内嵌服务器
部署WAR 包可执行 JAR
监控需要自行集成Actuator 开箱即用
上手难度较高快速上手
本质关系

Spring Boot 不是新框架,而是 Spring 的脚手架。它简化了 Spring 应用的搭建和配置,核心功能(IoC、AOP、事务等)全部来自 Spring Framework。

日志框架

Spring Boot 默认使用 SLF4J + Logback

application.yml
logging:
level:
root: INFO
com.example.service: DEBUG # 指定包的日志级别
org.springframework.web: WARN
file:
name: logs/app.log # 日志文件路径
logback:
rollingpolicy:
max-file-size: 100MB # 单文件大小
max-history: 30 # 保留天数
pattern:
console: "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"

全局异常处理

GlobalExceptionHandler.java
@RestControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Result<?>> handleValidation(MethodArgumentNotValidException e) {
String msg = e.getBindingResult().getFieldErrors().stream()
.map(err -> err.getField() + ": " + err.getDefaultMessage())
.collect(Collectors.joining("; "));
return ResponseEntity.badRequest().body(Result.fail(400, msg));
}

@ExceptionHandler(Exception.class)
public ResponseEntity<Result<?>> handleException(Exception e) {
log.error("系统异常", e);
return ResponseEntity.status(500).body(Result.fail(500, "系统繁忙"));
}
}

// 统一响应格式
public record Result<T>(int code, String message, T data) {
public static <T> Result<T> ok(T data) { return new Result<>(200, "success", data); }
public static <T> Result<T> fail(int code, String msg) { return new Result<>(code, msg, null); }
}

跨域处理

全局 CORS 配置
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("https://example.com")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600);
}
}

Spring Boot 测试

单元测试 + 集成测试
// 集成测试:启动完整的 Spring 上下文
@SpringBootTest
class OrderServiceTest {

@Autowired
private OrderService orderService;

@MockBean // Mock 掉外部依赖
private PaymentClient paymentClient;

@Test
void createOrder_success() {
when(paymentClient.charge(any())).thenReturn(PayResult.success());
Order order = orderService.createOrder(new OrderDTO("item-1", 100));
assertThat(order.getStatus()).isEqualTo("PAID");
}
}

// Controller 层测试:只加载 Web 层
@WebMvcTest(UserController.class)
class UserControllerTest {

@Autowired
private MockMvc mockMvc;

@MockBean
private UserService userService;

@Test
void getUser_returnsUser() throws Exception {
when(userService.findById(1L)).thenReturn(new User(1L, "Alice"));
mockMvc.perform(get("/api/users/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name").value("Alice"));
}
}

常见面试问题

Q1: Spring Boot 的启动流程?

答案

  1. main() 调用 SpringApplication.run()
  2. 推断应用类型(Servlet/Reactive)
  3. 加载 ApplicationContextInitializerApplicationListener
  4. 创建 Environment,加载配置文件
  5. 打印 Banner
  6. 创建 ApplicationContext
  7. refreshContext():扫描 Bean 定义、创建 Bean、启动内嵌 Web 服务器
  8. 执行 CommandLineRunner / ApplicationRunner

Q2: Spring Boot 和 Spring 的区别?

答案

Spring Boot 是 Spring 的脚手架,核心功能来自 Spring。它提供自动配置(减少手动配置)、Starter(简化依赖管理)、内嵌服务器(简化部署)、Actuator(生产监控)。开发者只需关注业务逻辑,Spring Boot 处理基础设施。

Q3: 如何实现 Spring Boot 应用的热部署?

答案

开发环境使用 spring-boot-devtools

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>

它会在代码变更后自动重启应用(使用两个 ClassLoader,只重新加载用户类)。生产环境不要使用。

Q4: @SpringBootApplication 包含哪些注解?

答案

@SpringBootApplication = @SpringBootConfiguration(配置类) + @EnableAutoConfiguration(自动配置) + @ComponentScan(包扫描)。

Q5: Spring Boot 如何实现统一响应格式?

答案

// 方式1:封装 Result 类 + 手动包装
public Result<User> getUser() {
return Result.ok(userService.findById(id));
}

// 方式2:ResponseBodyAdvice(全局自动包装)
@RestControllerAdvice
public class ResponseWrapper implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(...) { return true; }

@Override
public Object beforeBodyWrite(Object body, ...) {
if (body instanceof Result) return body;
return Result.ok(body);
}
}

Q6: Spring Boot 打成 JAR 和 WAR 的区别?

答案

  • JAR(默认):内嵌服务器,java -jar 直接运行。适合微服务和容器化部署
  • WAR:需部署到外部 Tomcat。适合传统部署方式或需要和其他应用共享 Tomcat

一般推荐 JAR 方式,除非有特殊的运维要求必须使用外部 Tomcat。

相关链接