源本科技 | 码上会

Spring 高频面试题及参考答案

2026/04/05
1
0

Spring Bean生命周期

Spring Bean 的生命周期就是 Bean 从创建到销毁的全过程,通俗说就是实例化→属性填充→初始化→使用→销毁五步。首先容器通过反射实例化 Bean,接着进行依赖注入,填充属性和依赖对象;然后执行初始化相关方法,比如 @PostConstruct 注解的方法、InitializingBean 的 afterPropertiesSet;之后 Bean 就进入可用状态,被业务使用;当容器关闭时,会执行销毁方法,比如 @PreDestroy 的方法,完成资源释放。整个过程由 Spring IoC 容器全权管控,开发者不用手动管理对象的创建和销毁,只需要关注业务逻辑即可。

Spring依赖注入(DI)工作原理

依赖注入就是 Spring 帮我们自动把对象需要的依赖赋值好,不用自己 new 对象。比如 Service 需要 Dao,以前要手动创建 Dao 实例,现在交给 Spring 容器。容器启动时会扫描所有 Bean,识别出 Bean 之间的依赖关系,通过构造方法、setter 方法或者 @Autowired 注解,把依赖的 Bean 自动注入进去。核心是把对象的依赖控制权从代码自身转移到 Spring 容器,降低类之间的耦合,让代码更易维护、易测试,也符合面向对象的设计原则。

Spring AOP概念

AOP 叫面向切面编程,核心是把通用的非业务逻辑抽离出来,不侵入业务代码。像日志、事务、权限校验这些功能,每个方法都要用,写在业务里会很乱,AOP 就把它们做成“切面”。底层通过动态代理实现,目标方法执行时,代理对象会在前后插入切面逻辑。它不改变原有业务代码,就能统一增强功能,实现代码解耦。常见场景就是日志记录、事务管理、性能监控、权限控制,让业务代码只专注核心业务,通用逻辑单独维护。

Spring事务管理实现

Spring 事务管理主要分声明式事务编程式事务,日常用声明式最多。声明式通过 @Transactional 注解实现,底层靠 AOP 动态代理,方法执行前开启事务,执行无异常就提交,出现异常就回滚。编程式则是手动写代码控制事务开启、提交、回滚,灵活性高但代码繁琐。Spring 通过 TransactionManager 事务管理器对接不同数据源,统一管理事务流程,还支持事务传播、隔离级别等配置,让数据库事务控制变得简单,不用手动处理 JDBC 事务。

Spring MVC执行流程

Spring MVC 是 Web 层框架,核心是DispatcherServlet。用户发请求先到 DispatcherServlet,它通过 HandlerMapping 找到对应的 Controller 和方法;然后调用 HandlerAdapter 执行 Controller 方法,得到业务数据和视图信息;接着把结果交给 ViewResolver 视图解析器,找到对应的页面;最后渲染视图返回给用户。整个流程把请求分发、业务处理、视图渲染拆分开,结构清晰。DispatcherServlet 作为中央调度器,统一管理所有流程,开发者只需要写 Controller 和页面即可。

Spring Boot与Spring的区别

Spring 是核心框架,提供 IoC、AOP 等基础功能,但配置繁琐,要手动写大量 XML 或配置类。Spring Boot 是基于 Spring 的快速开发框架,核心是约定大于配置,自带自动配置和起步依赖,不用手动整合框架、管理版本。Spring 帮我们搭建底层容器,Spring Boot 则是快速搭建可运行项目,内置 Tomcat,省去部署步骤,开箱即用。简单说,Spring 是基础,Spring Boot 是 Spring 的快速开发工具,简化 Spring 项目的开发、配置、部署全流程。

Spring Cloud与Spring Boot的关系

Spring Cloud 是微服务治理套件,Spring Boot 是微服务开发框架,两者是搭配使用的关系。Spring Cloud 提供服务注册发现、配置中心、网关、熔断降级等微服务功能,但它不能独立使用,必须基于 Spring Boot 构建微服务项目。每个微服务都是 Spring Boot 项目,通过 Spring Cloud 实现微服务之间的协调治理。简单讲,Spring Boot 用来开发单个微服务,Spring Cloud 用来把多个微服务整合起来,形成完整的微服务架构。

Spring Security认证和授权机制

认证是验证用户身份,授权是判断用户能做什么。认证时,Security 通过过滤器拦截请求,拿到账号密码后,对接 UserDetailsService 查询用户信息,比对密码完成登录,生成令牌或 Session。授权则是在认证后,获取用户的权限角色,通过过滤器链校验用户是否有访问当前接口的权限。底层靠过滤器链、用户详情服务、权限注解实现,支持表单登录、JWT、OAuth 等多种方式,安全且扩展性强。

Spring Bean作用域

Spring Bean 有 6 种作用域,最常用的是单例(singleton)和原型(prototype)。单例是容器中只有一个实例,每次获取都是同一个,默认就是单例,适合无状态 Bean。原型是每次获取都创建新实例,适合有状态 Bean。另外还有 Web 环境下的请求(request)、会话(session)、应用(application)、websocket 作用域,分别对应一次请求、一个会话、整个 Web 应用、WebSocket 连接生命周期,满足不同场景的对象创建需求。

Spring IoC控制反转

IoC 叫控制反转,就是把对象的创建、管理、依赖注入的控制权,从代码转移到 Spring 容器。以前我们自己 new 对象、管理依赖,现在交给 Spring 容器。容器启动时扫描注解,创建 Bean 实例,自动注入依赖,管理整个生命周期。反转的是“对象控制权”,目的是降低代码耦合,不用在业务里硬编码创建对象,代码更灵活、易测试。IoC 是 Spring 的核心,AOP、事务等功能都是基于 IoC 容器实现的。

Spring Data JPA工作原理

Spring Data JPA 是对 JPA 的封装,简化数据库操作。它基于 Hibernate 实现,我们只需要写 Repository 接口,继承 JpaRepository,不用写 CRUD 代码,框架自动生成实现类。通过方法名规则,比如 findByName,框架自动解析生成 SQL;也可以用 @Query 自定义 SQL。它屏蔽了底层 JDBC 和 JPA 的复杂代码,统一数据访问层,支持分页、排序、复杂查询,让数据库操作变得极简,大幅减少样板代码。

Spring Boot自动配置实现

自动配置是 Spring Boot 的核心,靠 **@EnableAutoConfiguration** 实现。框架启动时,会读取 classpath 下 META-INF 里的自动配置类,根据条件注解,比如 @ConditionalOnClass、@ConditionalOnBean,判断当前项目引入了哪些依赖,自动配置对应的 Bean。比如引入 spring-boot-starter-web,就自动配置 Tomcat、Spring MVC。它按“约定大于配置”,帮我们自动整合框架、创建 Bean,不用手动写配置,实现开箱即用。

Spring Cloud服务发现和注册机制

服务注册发现是微服务的基础,常用 Nacos、Eureka 等组件。服务提供者启动时,会把自己的地址、端口、服务名注册到注册中心;服务消费者要调用服务时,从注册中心拉取对应服务的实例列表。注册中心会通过心跳检测服务状态,剔除故障实例。消费者本地缓存服务列表,直接调用,不用硬编码地址。整个机制实现微服务的动态管理,服务上下线无感,保证集群稳定。

Spring事件和事件监听器

Spring 事件基于观察者模式,实现组件解耦通信。首先自定义事件继承 ApplicationEvent,然后创建监听器实现 ApplicationListener,或用 @EventListener 注解。当容器中发布事件时,所有监听该事件的监听器都会自动执行对应逻辑。比如项目启动、用户注册成功后触发通知,都可以用事件实现。它不用组件之间直接调用,降低耦合,让业务流程更清晰,扩展也更方便。

Spring事务传播行为

事务传播行为用来控制多个事务方法相互调用时,事务如何传递,一共有 7 种。最常用的是 REQUIRED,默认级别,有事务就加入,没有就新建;REQUIRES_NEW 是每次新建独立事务,外层事务不影响内层;SUPPORTS 有事务就用,没有就非事务运行。还有 NEVER、NOT_SUPPORTED 等禁用事务的类型。通过传播行为,能精准控制复杂业务下的事务范围,避免事务混乱,保证数据一致性。

Spring国际化(i18n)实现

Spring 国际化用来实现多语言切换,核心是 MessageSource 接口。我们在 resources 下创建不同语言的 properties 文件,比如 messages_zh_CN、messages_en_US,存放对应语言的文案。代码中通过 Locale 解析当前语言环境,调用 MessageSource 获取对应文案。支持页面和后端接口的多语言,通过请求头、Session 等方式切换 Locale,不用修改业务代码,就能适配不同国家地区的语言需求。

Spring JdbcTemplate操作数据库

JdbcTemplate 是 Spring 对 JDBC 的封装,解决原生 JDBC 代码繁琐的问题。它自动管理数据库连接、关闭资源、处理异常,我们只需要调用 API。通过 update 执行增删改,query、queryForObject 执行查询,传入 SQL 和参数即可。不用写注册驱动、获取连接、关闭连接等样板代码,简化数据库操作,同时保留 JDBC 的灵活性,适合简单的数据库操作场景,轻量且易用。

Spring Cloud Config工作原理

Spring Cloud Config 是集中配置中心,统一管理微服务配置。配置文件存在 Git、本地仓库等地方,Config Server 端拉取配置,各个微服务作为 Client 端,启动时从 Config Server 获取配置。配置修改后,通过刷新机制通知微服务更新,不用重启服务。它实现配置集中化、动态化,多环境配置统一管理,避免每个微服务单独维护配置,方便微服务集群的配置管理。

Spring Boot Actuator

Actuator 是 Spring Boot 的监控运维组件,用来查看项目运行状态。启动后提供多个监控接口,能查看 Bean 信息、健康状态、服务器指标、日志、请求映射等。方便运维人员监控服务是否正常、排查问题,也能对接 Prometheus 等监控系统。默认部分接口需要开启权限,配置简单,是 Spring Boot 项目运维必备组件,让服务可监控、可管理。

Spring数据访问异常层次

Spring 把不同数据库、不同数据访问框架的异常,统一封装成 DataAccessException 体系。不管是 JDBC、JPA、MyBatis 的异常,都会被转换成 Spring 的通用数据访问异常,屏蔽了底层数据库的差异。开发者不用捕获各种框架特有的异常,只需要处理 Spring 统一异常,代码更通用,切换数据库或框架时,异常处理代码不用修改,降低耦合。

Spring MVC和Spring WebFlux区别

Spring MVC 是同步阻塞式框架,基于 Servlet API,一个请求占一个线程,适合传统 Web 项目。Spring WebFlux 是响应式非阻塞框架,基于 Reactor,少量线程就能处理高并发请求,靠异步事件驱动,适合高并发、高吞吐的场景。MVC 开发简单,兼容传统组件;WebFlux 性能更高,但编程模型不同,生态组件少。简单说,常规项目用 MVC,高并发微服务用 WebFlux。

Spring中的Template设计模式

Template 模式是定义固定流程骨架,具体步骤交给子类实现。Spring 里大量使用该模式,比如 JdbcTemplate、RedisTemplate、RestTemplate。以 JdbcTemplate 为例,框架定义好获取连接、执行 SQL、释放资源的固定流程,而 SQL 执行、结果映射这些可变步骤,交给开发者实现。它把不变的流程封装好,可变部分开放扩展,减少重复代码,让开发者只关注业务逻辑,不用管通用流程。

Spring Security过滤器链

Spring Security 靠过滤器链实现安全控制,是一串有序的过滤器。每个过滤器负责不同功能,比如登录认证、权限校验、CSRF 防护、注销登录等。请求进来后按顺序经过过滤器,完成身份验证、权限判断,不符合安全规则就拦截。过滤器链可自定义增删,灵活适配不同安全需求,是 Security 实现认证授权的核心底层结构,所有安全逻辑都靠它串联执行。

Spring AOP实现日志记录

用 AOP 做日志非常简单,不侵入业务代码。先添加 AOP 依赖,创建切面类加 @Aspect,定义切点匹配需要打印日志的方法。然后用环绕通知 @Around,在方法执行前打印请求参数,执行后打印返回结果,出现异常打印异常信息。通过切点表达式精准匹配 Controller 或 Service 方法,统一管理日志格式,不用在每个方法里写日志代码,方便维护,也让业务代码更简洁。

BeanFactory和ApplicationContext区别

BeanFactory 是 Spring最基础的容器,只提供基本的 Bean 管理功能,懒加载,用到 Bean 时才创建。ApplicationContext 是 BeanFactory 的子接口,属于高级容器,启动时就预加载所有单例 Bean,还支持事件发布、国际化、资源加载、AOP 等扩展功能。日常开发全用 ApplicationContext,功能更强大,启动即完成 Bean 初始化;BeanFactory 只在内存极小的场景使用,满足基础容器需求。

Spring Boot自定义启动Banner

自定义 Banner 很简单,在 resources 目录下新建banner.txt 文件,把想要的文字、字符画放进去,启动项目就会自动加载。也可以在 application.yml 里配置 spring.banner.location 指定文件路径,还能关闭 Banner。Banner 只做启动展示,不影响项目功能,很多公司会改成自己的品牌字符画,个性化项目启动界面,配置零代码,非常简单。

Spring MVC HandlerInterceptor和Filter区别

Filter 是Servlet 规范的过滤器,拦截所有 Web 请求,在 Servlet 前后执行,依赖 Tomcat 容器。HandlerInterceptor 是Spring MVC 的拦截器,只拦截进入 Controller 的请求,属于 Spring 容器管理,能获取 Spring 的 Bean。Filter 功能更底层,拦截范围广;Interceptor 更贴合 Spring MVC,能获取 HandlerMethod、ModelAndView 等 Spring 相关对象,精细控制 Controller 请求。日常 Spring 项目优先用 Interceptor,更方便整合 Spring 功能。

Spring事务管理器TransactionManager

TransactionManager 是 Spring 事务的核心接口,负责事务的开启、提交、回滚。不同数据源有不同实现类,比如 JDBC 用 DataSourceTransactionManager,JPA 用 JpaTransactionManager。它屏蔽了底层事务的差异,为上层提供统一的事务操作 API,不管用什么数据访问框架,事务管理方式都一样。声明式事务底层就是靠它配合 AOP,实现自动事务控制,是 Spring 事务机制的核心支撑。

Spring框架中的设计模式

Spring 大量使用经典设计模式,最核心的有:单例模式,Bean 默认单例;工厂模式,BeanFactory、ApplicationContext 生产 Bean;动态代理模式,AOP 底层实现;模板模式,JdbcTemplate 等;观察者模式,事件监听器;装饰器模式,增强 Bean 功能;适配器模式,适配不同框架接口。这些设计模式让 Spring 结构清晰、扩展性强、代码优雅,也是 Spring 易用易扩展的原因。

Spring Boot Profiles

Profiles 用来实现多环境配置切换,比如开发、测试、生产环境。我们创建 application-dev.yml、application-test.yml、application-prod.yml,分别对应不同环境的配置。在主配置文件里用 spring.profiles.active 指定激活的环境,比如 dev,项目就会加载对应配置。不用修改代码,只切换配置文件,就能适配不同运行环境,方便项目在不同环境部署,避免配置混乱。

Spring异常处理

Spring 支持全局统一异常处理,核心是 @ControllerAdvice+@ExceptionHandler。创建全局异常类,加 @ControllerAdvice,然后针对不同异常写方法,加 @ExceptionHandler,统一返回错误信息。也可以用 @RestControllerAdvice 返回 JSON 格式异常。Spring MVC 还支持自定义错误页面、HandlerExceptionResolver。全局异常处理把分散的异常逻辑集中管理,代码整洁,前端接收格式统一,方便问题排查。

CommandLineRunner和ApplicationRunner区别

两者都是Spring Boot 启动后执行的逻辑,项目启动完成就自动运行。区别是入参不同:CommandLineRunner 的 run 方法参数是 String 数组,接收命令行参数;ApplicationRunner 的参数是 ApplicationArguments,能更方便解析命令行参数,区分选项参数和普通参数。功能基本一致,都是做项目启动后的初始化操作,比如加载数据、初始化配置,简单需求用 CommandLineRunner,复杂参数解析用 ApplicationRunner。

Spring Security OAuth2

OAuth2 是授权框架,Spring Security 集成它实现第三方登录,比如微信、GitHub 登录。它有四种授权模式,常用授权码模式。流程是用户跳转到第三方授权页面,授权后返回授权码,后端用授权码换取令牌,通过令牌获取用户信息。Spring Security 提供完整的 OAuth2 客户端、服务端实现,不用手动写授权流程,安全可靠,快速接入第三方登录,也能做自己的授权服务。