人人都会AI编程

附录 C Java Spring 高频面试题与核心考点

更新时间:2026-07-10

本附录梳理了 Java Spring 相关面试中最常出现的问题,涵盖核心容器、AOP、事务、Spring Boot、Spring MVC 以及微服务等方向。每个题目附有简要答案与考点分析,帮助你在理解的基础上抓住回答要领。


C.1 控制反转与依赖注入

Q1:什么是控制反转(IoC)?Spring 是如何实现 IoC 的?

参考答案:
控制反转是一种设计原则,将对象的创建、依赖管理和生命周期的控制权从应用程序代码转移给外部容器。在 Spring 中,这个容器就是 IoC 容器(ApplicationContext)。它通过读取配置(XML、注解或 Java Config)获取 Bean 的定义,利用反射创建对象并完成依赖注入,从而将各个组件松散地装配在一起。开发者只需声明依赖,不需要干涉对象的构造过程。

核心考点: IoC 的概念本质、IoC 与 DI 的关系、Spring 容器的角色。


Q2:Spring 中有哪些依赖注入方式?你推荐哪种?为什么?

参考答案:
三种:构造器注入、Setter 注入和字段注入(@Autowired 加在字段上)。

  • 构造器注入:依赖由构造函数传入,对象创建后即可用,不可变,强制依赖清晰,易于测试,是官方推荐的方式。
  • Setter 注入:适用于可选依赖或需要后续修改的场景,但对象可能处于不完整状态。
  • 字段注入:代码简洁,但隐藏了依赖关系,难以测试(需要反射注入),不符合面向对象封装原则,实际项目中应谨慎使用。

核心考点: 三种注入的区别、优缺点、实际选型依据。


C.2 Bean 生命周期与作用域

Q3:描述 Spring Bean 的生命周期。

参考答案:
大致流程:

  1. 实例化:容器根据 Bean 定义通过反射创建对象实例。
  2. 属性填充:注入依赖的属性值。
  3. Aware 回调:如果 Bean 实现了 BeanNameAwareBeanFactoryAwareApplicationContextAware 等接口,依次回调。
  4. 前置处理:遍历 BeanPostProcessorpostProcessBeforeInitialization 方法。
  5. 初始化:若实现了 InitializingBean 则调用 afterPropertiesSet();若指定了 init-method 则调用该方法。
  6. 后置处理:遍历 BeanPostProcessorpostProcessAfterInitialization(这里是 AOP 代理生成的关键时机)。
  7. Bean 就绪:可以正常使用。
  8. 销毁:容器关闭时,若实现 DisposableBean 则调用 destroy(),或调用指定的 destroy-method

核心考点: 全生命周期的关键节点,尤其是 BeanPostProcessor 的作用(AOP 基于此)。


Q4:Spring 中 Bean 的作用域有哪些?prototype 与 singleton 区别?

参考答案:

  • singleton(默认):整个容器中仅一个实例,所有请求共享。适合无状态服务。
  • prototype:每次获取都创建新实例。适合有状态对象。
  • request / session / application / websocket:仅 Web 环境有效,分别绑定到 HTTP 请求、会话、ServletContext、WebSocket 生命周期。

区别:singleton 生命周期由容器完全管理,prototype 在创建后容器不再负责销毁(需客户端自行释放资源)。若 singleton 依赖 prototype,单例内的 prototype 只会注入一次,需使用 ObjectFactory@Lookup 动态获取。

核心考点: 作用域适用场景、prototype 的陷阱。


C.3 面向切面编程

Q5:什么是 AOP?它解决了什么问题?

参考答案:
AOP(Aspect-Oriented Programming)通过将横切关注点(如日志、事务、安全)从业务逻辑中分离出来,封装成切面,在运行时动态织入目标方法,实现代码复用和核心业务的纯净性。它解决了传统 OOP 中代码散乱和模块纠缠的问题,大幅提升可维护性。

核心考点: AOP 的设计初衷、与 OOP 的互补关系。


Q6:Spring AOP 的底层实现原理?它与 AspectJ 的区别?

参考答案:
Spring AOP 基于动态代理

  • 若目标对象实现了接口,使用 JDK 动态代理(java.lang.reflect.Proxy)。
  • 若没有实现接口,使用 CGLIB 动态字节码生成子类代理。

与 AspectJ 的区别

  • Spring AOP 是运行时织入,只支持方法级别的拦截,性能略低但使用简单,是 Spring 集成的一部分。
  • AspectJ 提供编译时、类加载时织入,功能更强大(可拦截字段、构造函数等),需额外的编译器或织入工具,但性能更好。

核心考点: 动态代理的选择策略、两者的适用场景。


C.4 事务管理

Q7:Spring 的声明式事务是如何实现的?@Transactional 失效的场景有哪些?

参考答案:
声明式事务基于 AOP 实现。容器为标注 @Transactional 的类生成代理,在方法前后执行事务开启、提交或回滚。
常见失效场景

  1. 方法非 public:Spring AOP 默认只代理 public 方法。
  2. 自调用:类内部通过 this.method() 调用,不经过代理对象,事务不生效(需通过 AopContext.currentProxy() 或注入自身)。
  3. 异常被捕获:若在方法内捕获取消了异常,事务不会回滚;默认只回滚 RuntimeExceptionError
  4. 数据库引擎不支持:如 MyISAM 不支持事务。
  5. 事务传播行为设置错误:例如 Propagation.NOT_SUPPORTED 会挂起当前事务。
  6. 类未托管:调用的是非 Spring Bean 的方法。

核心考点: AOP 代理的原理、事务失效的排查思路。


Q8:Spring 的事务传播行为有哪些?举例说明 REQUIRED 和 REQUIRES_NEW 的区别。

参考答案:
七种传播行为:

  • REQUIRED(默认):当前有事务则加入,无则新建。
  • REQUIRES_NEW:始终新建事务,挂起当前事务。
  • SUPPORTS:有则加入,无则非事务执行。
  • NOT_SUPPORTED:非事务执行,挂起当前事务。
  • MANDATORY:必须在事务中运行,否则抛异常。
  • NEVER:不能在事务中运行,否则抛异常。
  • NESTED:嵌套事务,内层事务可单独回滚,外层不影响。

区别举例:转账操作中调用记录日志。若日志使用REQUIRES_NEW,即使转账回滚,日志也已提交;若用REQUIRED,日志将与转账同事务一起回滚。

核心考点: 传播行为的适用场景,尤其是 REQUIRED 和 REQUIRES_NEW 的业务影响。


C.5 Spring Boot 基础

Q9:Spring Boot 的自动配置原理是什么?

参考答案:

  1. @SpringBootApplication 包含 @EnableAutoConfiguration,该注解通过 @Import 导入 AutoConfigurationImportSelector
  2. 该类读取 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(或较早版本的 spring.factories)中列出的自动配置类全限定名。
  3. 每个自动配置类通过 @ConditionalOnClass@ConditionalOnMissingBean 等条件注解判断是否生效。
  4. 匹配成功则自动创建并注册 Bean(如数据源、Web 服务器等),实现一键集成。

核心考点: @EnableAutoConfiguration 机制、条件注解的运用。


Q10:如何自定义 Starter?关键步骤是什么?

参考答案:

  1. 创建 autoconfigure 模块,撰写自动配置类(@Configuration + 条件注解)。
  2. META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 中添加配置类路径。
  3. 编写 spring-boot-starter-xxx 模块,仅引入 autoconfigure 模块及必要三方依赖。
  4. (可选)提供 application.properties 前缀属性,使用 @ConfigurationProperties 接收参数,并在配置类中启用 @EnableConfigurationProperties

核心考点: Starter 的结构、自动配置脚本的注册位置。


C.6 Spring MVC

Q11:描述 Spring MVC 的请求处理流程。

参考答案:

  1. 请求到达前端控制器 DispatcherServlet
  2. DispatcherServlet 调用 HandlerMapping 获取匹配的 HandlerExecutionChain(包含拦截器和处理器)。
  3. 通过 HandlerAdapter 执行具体的处理器(Controller)。
  4. 处理器返回 ModelAndView(或通过 @ResponseBody 直接写回数据)。
  5. 视图解析器 ViewResolver 解析逻辑视图名为具体视图(JSP、Thymeleaf 等)。
  6. 渲染视图并返回响应。

核心考点: 前端控制器模式、各组件的职责。


Q12:@RestController@Controller 的区别?

参考答案:

  • @Controller 用于定义控制器,方法返回值通常是视图名(配合 @ResponseBody 可返回 JSON)。
  • @RestController@Controller + @ResponseBody 的合体,类中所有方法都直接返回 JSON/XML 等数据,适合 REST API。

核心考点: REST 风格与视图渲染的区分。


C.7 Spring Security

Q13:Spring Security 的过滤器链是如何工作的?简述认证流程。

参考答案:
Spring Security 基于 FilterChainProxy 管理一系列安全过滤器(如 UsernamePasswordAuthenticationFilterBearerTokenAuthenticationFilter)。认证流程(以表单登录为例):

  1. 用户提交用户名密码,UsernamePasswordAuthenticationFilter 将其封装为 UsernamePasswordAuthenticationToken
  2. 调用 AuthenticationManager(核心接口),其实现 ProviderManager 委托给一组 AuthenticationProvider
  3. 例如 DaoAuthenticationProvider 通过 UserDetailsService 加载用户信息,比对密码。
  4. 认证通过后,将包含权限的 Authentication 对象存入 SecurityContextHolder(默认 ThreadLocal)。

核心考点: 过滤器链结构、认证核心接口。


C.8 微服务与 Spring Cloud

Q14:Spring Cloud 的核心组件及其功能?

参考答案:

  • 服务发现:Eureka、Consul、Nacos,负责服务注册与发现。
  • 配置中心:Spring Cloud Config、Nacos,集中管理配置并支持动态刷新。
  • 负载均衡:Spring Cloud LoadBalancer(先前的 Ribbon),客户端负载均衡。
  • 远程调用:OpenFeign,声明式 HTTP 客户端。
  • 断路器:Resilience4j / Sentinel,防止级联故障。
  • 网关:Spring Cloud Gateway,统一入口、路由、过滤。
  • 消息总线:Spring Cloud Bus,配合 Config 实现广播配置变更。
  • 流式消息:Spring Cloud Stream,屏蔽底层 MQ 差异。

核心考点: 组件体系的整体理解,不要只记名词而要懂用途。


Q15:如何理解服务雪崩?Sentinel 或 Resilience4j 如何解决?

参考答案:
服务雪崩:微服务链路上一个服务不可用,导致故障沿依赖链向上蔓延,最终整个系统瘫痪。
解决思路:

  • 熔断:当失败率达到阈值时,快速失败,不再调用故障服务。
  • 降级:提供 fallback 逻辑,返回默认值或友好提示。
  • 隔离:线程池或信号量隔离,限制对单个服务的资源占用。
  • 限流:控制 QPS,避免过载。

核心考点: 高可用治理的核心理念,能结合工具说明实现机制。


以上问题覆盖了 Spring 面试的主线考点。真正面试时,考官往往会刨根问底,建议结合本书相关章节深入理解原理,而非死记硬背。掌握这些骨架,再填充项目中的真实案例,面试通过率将大幅提升。