树码科技 | 技术博客

Spring 高频面试题及参考答案

2026/04/05
42
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客户端、服务端实现,不用手动写授权流程,安全可靠,快速接入第三方登录,也能做自己的授权服务。