news 2026/10/8 6:53:21

Spring Boot 核心知识点总结,面试再也不怕了!

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring Boot 核心知识点总结,面试再也不怕了!

一、Spring Boot 概述

1.1 为什么需要 Spring Boot

传统 Spring 项目存在三大痛点:

  • 依赖版本冲突:手动管理依赖版本,容易出现版本不兼容。

  • 配置繁琐:大量 XML 或 Java 配置类,启动慢、维护成本高。

  • 部署复杂:需要外部 Servlet 容器,打包、部署、运维链路长。

Spring Boot 通过起步依赖、自动配置、内嵌容器三大核心能力,系统性地解决了上述问题。

1.2 核心特性

特性说明
起步依赖(Starter)将常用依赖以固定版本打包,引入一个 starter 即可获得一组匹配依赖
自动配置(Auto Configuration)根据类路径和已定义的 Bean,自动完成大量默认配置
内嵌容器内嵌 Tomcat、Jetty 或 Undertow,可打成 JAR 包独立运行
Actuator提供生产可用的监控端点,如健康检查、指标、环境信息等
外部化配置支持 properties、YAML、环境变量、命令行参数等多种来源,且有明确优先级

1.3 Spring Boot 与 Spring、Spring Cloud 的关系

  • Spring:核心框架,提供 IoC、AOP、数据访问、Web 等基础能力。

  • Spring Boot:在 Spring 之上的快速开发脚手架,解决配置和部署复杂度。

  • Spring Cloud:基于 Spring Boot 构建,提供微服务治理能力,如服务注册发现、配置中心、网关、熔断等。

三者是层层递进、相互配合的关系,面试中常常会考察对这一关系的理解。


二、自动配置原理

自动配置是 Spring Boot 面试中的绝对高频考点。要讲清楚自动配置,必须从@SpringBootApplication注解和SpringFactoriesLoader机制入手。

2.1 @SpringBootApplication 背后的三个注解

@SpringBootApplication是一个组合注解,等价于同时声明了以下三个注解:

  • @SpringBootConfiguration:本质是@Configuration,标记当前类是配置类。

  • @EnableAutoConfiguration:开启自动配置,是核心所在。

  • @ComponentScan:开启组件扫描,默认扫描启动类所在包及其子包。

简化源码结构:

java

@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) public @interface SpringBootApplication { }

2.2 自动配置的加载流程

自动配置的入口是@EnableAutoConfiguration,其内部通过@Import(AutoConfigurationImportSelector.class)导入选择器。整体流程如下:

  1. 启动类上的@EnableAutoConfiguration触发AutoConfigurationImportSelector。

  2. 该选择器调用SpringFactoriesLoader.loadFactoryNames方法。

  3. 从类路径下所有META-INF/spring.factories文件(以及 Spring Boot 2.7 之后推荐的META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports)中读取自动配置类全限定名。

  4. 通过@Conditional系列条件注解对候选配置类进行过滤。

  5. 符合条件的配置类被加载为 Bean,完成默认配置。

核心流程伪代码:

java

public class AutoConfigurationImportSelector { protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { // 从 META-INF/spring.factories 读取 EnableAutoConfiguration 对应的配置类列表 List<String> configurations = SpringFactoriesLoader.loadFactoryNames( getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()); return configurations; } }

2.3 条件注解体系

自动配置之所以能“按需生效”,依赖的是 Spring 提供的条件注解:

条件注解作用
@ConditionalOnClass当类路径下存在指定类时生效
@ConditionalOnMissingClass当类路径下不存在指定类时生效
@ConditionalOnBean当容器中存在指定 Bean 时生效
@ConditionalOnMissingBean当容器中不存在指定 Bean 时生效
@ConditionalOnProperty当配置文件中存在指定属性且值为指定值时生效
@ConditionalOnWebApplication当当前应用是 Web 应用时生效
@ConditionalOnExpression当 SpEL 表达式结果为 true 时生效

经典应用场景:引入spring-boot-starter-data-redis且类路径存在RedisTemplate相关类时,RedisAutoConfiguration才会被激活。

2.4 自定义 Starter 的思路

  1. 创建配置工程,定义自动配置类,使用@Configuration和@Bean提供核心对象。

  2. 在META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports或spring.factories中注册配置类。

  3. 通过@ConfigurationProperties提供可配置属性。

  4. 用@ConditionalOnMissingBean等注解保证可被用户覆盖。

  5. 单独拆分xxx-spring-boot-autoconfigure与xxx-spring-boot-starter两个模块。


三、Spring Boot 启动流程

Spring Boot 应用的启动本质是执行SpringApplication.run方法。

3.1 启动流程图

3.2 关键步骤详解

  1. 创建 SpringApplication 实例:推断应用类型(有无 Web 环境),加载ApplicationContextInitializer和ApplicationListener。

  2. 准备环境:创建ConfigurableEnvironment,加载配置文件和环境变量,并发布环境准备事件。

  3. 创建应用上下文:根据应用类型创建AnnotationConfigApplicationContext、AnnotationConfigServletWebServerApplicationContext或AnnotationConfigReactiveWebServerApplicationContext。

  4. 执行刷新:调用经典 Spring 的refresh方法,完成 Bean 的创建、依赖注入、初始化等过程。

  5. 执行 Runner:容器刷新完毕后,依次执行ApplicationRunner和CommandLineRunner接口的实现类。

启动完成后执行初始化逻辑的示例:

java

@Component public class DataInitRunner implements CommandLineRunner { @Override public void run(String... args) throws Exception { System.out.println("容器启动完成,执行数据初始化..."); } }

四、配置文件与多环境管理

4.1 配置文件格式

Spring Boot 支持application.properties和application.yml。YAML 层级清晰,适合复杂配置;properties 更简单直观。

yaml

server: port: 8080 servlet: context-path: /api spring: application: name: demo-service datasource: url: jdbc:mysql://localhost:3306/demo username: root password: 123456

4.2 多环境配置

使用application-{profile}.yml区分环境,并在主配置中激活:

yaml

# application.yml spring: profiles: active: dev

yaml

# application-dev.yml server: port: 8081 spring: datasource: url: jdbc:mysql://localhost:3306/dev_db

也可以在启动命令中动态指定:

bash

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

4.3 配置属性优先级

从高到低大致如下:

  1. 命令行参数

  2. Java 系统属性

  3. 操作系统环境变量

  4. jar 包外部的application-{profile}.yml

  5. jar 包内部的application-{profile}.yml

  6. jar 包外部的application.yml

  7. jar 包内部的application.yml

  8. @PropertySource引入的配置

  9. 默认配置

面试提示:至少记住“命令行参数优先级最高,其次环境变量,然后是外部配置文件,最后是内部配置文件”这条主线。

4.4 配置绑定

使用@ConfigurationProperties将配置项批量绑定到实体类,比逐个使用@Value更清晰:

java

@Component @ConfigurationProperties(prefix = "app.upload") public class UploadProperties { private String path; private long maxSize; private List<String> allowTypes; // getter / setter 省略 }

yaml

app: upload: path: /data/upload max-size: 10485760 allow-types: - jpg - png - pdf

五、常用注解详解

5.1 核心组件类注解

注解作用
@Component通用组件,将类交给 Spring 容器管理
@Service业务层组件,语义上是 @Component 的特化
@Repository数据访问层组件,额外支持异常翻译
@Controller控制层组件,处理 Web 请求
@RestController等于 @Controller 加 @ResponseBody,返回 JSON 数据
@Configuration标记配置类,内部 @Bean 方法会被代理增强
@Bean在配置类中声明 Bean,方法名默认作为 Bean 名称
@Scope指定 Bean 作用域,如 singleton、prototype
@Lazy延迟初始化 Bean

5.2 依赖注入类注解

注解说明
@AutowiredSpring 提供,默认按类型注入,可结合 @Qualifier 按名称注入
@ResourceJDK 提供,默认按名称注入,找不到名称再按类型注入
@Qualifier配合 @Autowired 指定注入 Bean 名称
@Value注入简单属性值,支持 SpEL 表达式

@Autowired 与 @Resource 的区别:

  • 来源不同:@Autowired 来自 Spring 框架,@Resource 来自 JDK 的 javax.annotation 包。

  • 注入顺序不同:@Autowired 默认按类型注入,@Resource 默认按名称注入。

  • 配合方式不同:@Autowired 配合 @Qualifier 使用,@Resource 通过 name 属性指定。

  • 是否强制不同:@Autowired 支持 required=false,@Resource 没有此参数,但其行为类似默认必须找到。

5.3 Web 相关注解

注解作用
@RequestMapping类或方法级别的请求映射,可指定路径、方法、参数等
@GetMapping/@PostMapping/@PutMapping/@DeleteMapping对应 HTTP 方法的具体映射
@PathVariable从 URL 路径中获取参数,如 /user/{id}
@RequestParam从请求查询参数或表单中获取参数
@RequestBody将请求体 JSON 反序列化为对象
@ResponseBody将方法返回值序列化为 JSON 写回响应
@RequestHeader读取请求头信息
@CookieValue获取 Cookie 中指定名称的值
@SessionAttribute获取 HttpSession 中保存的属性
@ModelAttribute将请求参数绑定到模型对象,常用于表单回显和公共数据初始化
@ExceptionHandler处理 Controller 中抛出的指定异常
@ControllerAdvice/@RestControllerAdvice全局异常处理、全局数据绑定和全局模型增强
@ResponseStatus指定响应状态码,可配合自定义异常返回对应 HTTP 状态
@Valid/@Validated开启参数校验,@Valid 是标准 JSR-303,@Validated 是 Spring 扩展,支持分组校验

六、参数校验与全局异常处理

6.1 参数校验常用注解

注解说明
@NotNull不能为 null
@NotBlank字符串不能为 null 且去除首尾空格后长度大于 0
@NotEmpty字符串、集合或数组不能为 null 且长度或大小大于 0
@Size(min, max)校验字符串、集合或数组的长度范围
@Min(value)数值必须大于或等于指定值
@Max(value)数值必须小于或等于指定值
@Email校验邮箱格式
@Pattern(regexp)按正则表达式校验字符串

在 DTO 上添加校验注解,并在 Controller 方法参数前使用@Valid开启校验:

java

public class UserCreateRequest { @NotBlank(message = "用户名不能为空") private String username; @Email(message = "邮箱格式不正确") private String email; @Size(min = 6, max = 20, message = "密码长度必须在 6 到 20 之间") private String password; // getter / setter 省略 } @RestController @RequestMapping("/users") public class UserController { @PostMapping public Result<Long> create(@Valid @RequestBody UserCreateRequest request) { // 校验通过后执行业务逻辑 return Result.success(userService.create(request)); } }

6.2 全局异常处理

使用@RestControllerAdvice配合@ExceptionHandler实现全局统一异常处理:

java

@RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(MethodArgumentNotValidException.class) public Result<Void> handleValidException(MethodArgumentNotValidException e) { String message = e.getBindingResult().getFieldErrors() .stream() .map(FieldError::getDefaultMessage) .collect(Collectors.joining("; ")); return Result.fail(400, message); } @ExceptionHandler(BusinessException.class) public Result<Void> handleBusinessException(BusinessException e) { return Result.fail(e.getCode(), e.getMessage()); } @ExceptionHandler(Exception.class) public Result<Void> handleException(Exception e) { log.error("系统异常", e); return Result.fail(500, "系统繁忙,请稍后再试"); } }

面试中经常被追问的几点:参数校验异常需要放在最后兜底、自定义异常要区分业务错误码、不要直接把异常堆栈返回给客户端。


七、拦截器、过滤器与监听器

7.1 过滤器 Filter

过滤器属于 Servlet 规范,作用于请求进入 Servlet 容器之后、到达 Controller 之前,以及响应返回客户端之前。

java

@Component public class RequestTimeFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { long start = System.currentTimeMillis(); chain.doFilter(request, response); long cost = System.currentTimeMillis() - start; System.out.println("请求耗时:" + cost + " ms"); } }

7.2 拦截器 HandlerInterceptor

拦截器属于 Spring MVC 体系,依赖 Spring 容器,常用于权限校验、登录检查、接口统计等:

java

@Component public class AuthInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String token = request.getHeader("Authorization"); if (!StringUtils.hasText(token)) { throw new BusinessException(401, "未登录"); } return true; } } @Configuration public class WebConfig implements WebMvcConfigurer { private final AuthInterceptor authInterceptor; public WebConfig(AuthInterceptor authInterceptor) { this.authInterceptor = authInterceptor; } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(authInterceptor) .addPathPatterns("/api/**") .excludePathPatterns("/api/login", "/api/register"); } }

7.3 过滤器与拦截器的区别

对比项过滤器 Filter拦截器 HandlerInterceptor
所属规范Servlet 规范Spring MVC 框架
依赖容器Servlet 容器Spring 容器
触发时机进入 DispatcherServlet 之前进入 Controller 方法之前
应用场景编码、跨域、日志等通用处理登录校验、权限校验等业务处理

7.4 监听器

监听器可以监听 Servlet 容器生命周期事件和 Spring 容器事件。常问ApplicationRunner与CommandLineRunner的区别:两者都在应用启动完成后执行,ApplicationRunner参数是ApplicationArguments,CommandLineRunner参数是原始字符串数组。

java

@Component public class ApplicationReadyListener { @EventListener(ApplicationReadyEvent.class) public void onReady() { System.out.println("应用已就绪"); } }

八、事务管理

8.1 @Transactional 核心属性

  • propagation:事务传播行为,默认 REQUIRED。

  • isolation:事务隔离级别,默认使用数据库默认隔离级别。

  • readOnly:只读事务,适合查询方法。

  • rollbackFor:指定哪些异常触发回滚,默认只有 RuntimeException 和 Error 回滚。

  • timeout:事务超时时间。

java

@Transactional(rollbackFor = Exception.class, timeout = 30) public void createOrder(OrderCreateRequest request) { // 业务代码 }

8.2 事务传播行为

传播行为含义
REQUIRED有事务则加入,没有则新建事务,最常见
REQUIRES_NEW总是新建事务,并挂起当前事务
SUPPORTS有事务则加入,没有则以非事务方式执行
NOT_SUPPORTED总是以非事务方式执行,并挂起当前事务
MANDATORY必须在事务中执行,否则抛异常
NEVER必须以非事务方式执行,否则抛异常
NESTED嵌套事务,内层事务可以独立回滚

面试常问「REQUIRED 和 REQUIRES_NEW 的区别」:REQUIRED 跟随外部事务一起提交或回滚;REQUIRES_NEW 独立开启新事务,内层方法提交后不受外层回滚影响。

8.3 事务失效常见场景

  • 自调用:同一个类内部方法直接调用,没有经过代理对象。

  • 方法不是 public:@Transactional 只对 public 方法生效。

  • 异常被捕获:方法内捕获并吞噬异常,框架感知不到异常不会回滚。

  • rollbackFor 不匹配:抛出受检异常但未配置 rollbackFor。

  • 数据源或事务管理器不匹配:多数据源场景下没有指定正确的事务管理器。

  • 不被 Spring 管理:类没有注册为 Bean,或是在非 Spring 线程中调用。


九、缓存使用

9.1 缓存注解

常用注解包括@Cacheable、@CachePut、@CacheEvict和@Caching。

java

@Cacheable(cacheNames = "user", key = "#id") public User getUserById(Long id) { return userMapper.selectById(id); } @CachePut(cacheNames = "user", key = "#user.id") public User updateUser(User user) { userMapper.updateById(user); return user; } @CacheEvict(cacheNames = "user", key = "#id") public void deleteUser(Long id) { userMapper.deleteById(id); }
  • @Cacheable会在方法执行前先查缓存,命中则直接返回。

  • @CachePut始终执行方法并更新缓存。

  • @CacheEvict执行方法后删除缓存。

9.2 缓存穿透、击穿、雪崩

问题含义常见解决思路
缓存穿透请求不存在的数据,每次都绕过缓存直接打到数据库缓存空值、布隆过滤器、参数校验
缓存击穿热点 key 过期瞬间大量请求同时访问数据库热点不过期、互斥锁重建缓存
缓存雪崩大量 key 同一时间过期或缓存服务不可用随机过期时间、本地缓存兜底、多级缓存

回答时要区分三者的定义、触发条件和应对措施。


十、日志框架

Spring Boot 默认使用 SLF4J 作为日志门面,并引入 Logback 作为默认实现。使用日志门面的好处在于业务代码不直接依赖具体日志实现,后续可无感切换。

java

@Slf4j @RestController public class LogDemoController { @GetMapping("/log") public String logDemo() { log.info("info 级别日志:{}", "示例参数"); return "ok"; } }

在application.yml中可通过logging.level、logging.file.name等属性配置日志级别和输出文件。


十一、总结

Spring Boot 的核心可以浓缩为以下几句话:

  1. 定位:Spring Boot 不是 Spring 的替代,而是在 Spring 之上的快速开发脚手架。

  2. 三大能力:起步依赖解决依赖管理,自动配置解决配置繁琐,内嵌容器解决部署复杂。

  3. 自动配置:入口是@EnableAutoConfiguration→AutoConfigurationImportSelector→SpringFactoriesLoader,通过@Conditional系列注解按需生效。

  4. 启动流程:SpringApplication.run→ 准备环境 → 创建上下文 → refresh → 执行 Runner。

  5. 配置管理:多环境 profile、外部化配置优先级、@ConfigurationProperties批量绑定。

  6. Web 开发:注解体系、参数校验、全局异常处理、Filter/Interceptor/Listener 三者区别。

  7. 数据与缓存:声明式事务、事务失效场景、缓存三大问题与应对。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/8 6:51:46

脆肉罗非大型批发商甄选:从鱼塘到餐桌的鲜活供应链实力参考

脆肉罗非基础常识科普&#xff1a;了解产品才能选对供应商很多餐饮新手刚接触脆肉罗非&#xff0c;会把它和普通罗非鱼混为一谈&#xff0c;其实脆肉罗非和普通罗非完全是两类产品&#xff0c;核心差异从养殖阶段就已经决定。脆肉罗非本身是经过品种改良的罗非鱼养殖品种&#…

作者头像 李华
网站建设 2026/10/8 6:51:45

注意!扬州高职单招机构排名出炉,选错至少耽误3年!

注意&#xff01;扬州高职单招机构排名出炉&#xff0c;选错至少耽误3年&#xff01;对于扬州及周边地区的中职、普高及往届考生而言&#xff0c;高职单招是通往理想大学的重要通道。随着江苏高职单招竞争日趋激烈&#xff0c;市面上各类集训机构层出不穷&#xff0c;一份非官方…

作者头像 李华
网站建设 2026/10/8 6:51:06

Java TCP聊天室实战:从Socket连接到消息广播完整链路

简介&#xff1a;这份资源是面向Java初学者与网络编程进阶者的TCP网络通信聊天室完整项目包&#xff0c;围绕客户端与服务器端实时交互场景&#xff0c;帮助读者理解面向连接、可靠传输的TCP协议原理及Java网络编程API的实际运用。包内共15个文件&#xff0c;以java源码、class…

作者头像 李华
网站建设 2026/10/8 6:51:02

oracle坏块导致备份不了

问题&#xff1a; Oracle 数据文件出现坏块&#xff08;典型报错 ORA-01578 数据块损坏、ORA-19566 坏块数超过 MAXCORRUPT 限制&#xff09;&#xff0c;导致 RMAN 备份无法完成、备份任务失败&#xff0c;需要既处理坏块又让备份能够跑完。 方案&#xff1a; 场景一&#xff…

作者头像 李华
网站建设 2026/10/8 6:50:57

用图构建会思考的AI助手:LangGraph实战教程

企业AI全栈学习地图 L3 Agent架构设计 | 构建自主决策的下一代AI助手 第三十六篇&#xff1a;# LangGraph 保姆级教程&#xff1a;用图把 AI Agent 的思考流程画出来&#xff0c;再造一个能帮你规划旅游的机器人先说一个挺烦的事。很多教程讲 LangGraph&#xff0c;一上来就甩…

作者头像 李华