Skip to content

面试题蒸馏卡:Spring 框架

语雀-Java开发/Spring全家桶 58 篇提炼的高频面试题。每题按「标准答 → 追问链 → 常见误解」组织。详细机制见对应概念卡。

Q1:说说 Spring 的 IoC 和 DI?

标准答:IoC(控制反转)是把「创建对象、管理依赖」的控制权从程序反转到容器的思想,DI(依赖注入)是它的实现。Spring 容器创建 Bean 后自动注入依赖,调用者无需 new、无需主动获取,实现松耦合。DI 有三种方式:setter 注入、构造器注入、字段注入,官方推荐构造器注入

追问链

  • "IoC 和 DI 是一回事吗?" → IoC 是思想,DI 是实现;还有 Service Locator 等其它实现
  • "三种注入方式区别?" → setter 先无参构造再注入(依赖可缺)、构造器创建即注入(依赖必需)、字段注入反射赋值(最简洁但难测试)
  • "为什么推荐构造器注入?" → 依赖强制必需、字段可 final 不可变、易做单元测试

常见误解:❌ 把 IoC 和 DI 混为一谈;❌ 以为字段注入最方便就该多用。

Q2:@SpringBootApplication 的原理?

标准答:它是复合注解,核心三件——@SpringBootConfiguration(=@Configuration)+ @ComponentScan(扫自己包)+ @EnableAutoConfiguration(自动装配)。自动装配靠 @Import(AutoConfigurationImportSelector) 从 classpath 的 META-INF/spring.factories(Boot 2.7 起改为 AutoConfiguration.imports)加载配置类,经去重、排除、条件过滤后注册进容器。

追问链

  • "@ComponentScan 和 @EnableAutoConfiguration 区别?" → 前者扫自己包的 @Component,后者装配第三方 jar 的配置类
  • "自动装配条件过滤是什么?" → @ConditionalOnClass/@ConditionalOnBean/@ConditionalOnMissingBean
  • "starter 和自动装配什么关系?" → starter = 依赖聚合 + 自动配置类,光引依赖没配置类不会自动装配

常见误解:❌ 以为自动装配就是 @ComponentScan;❌ 以为 spring.factories 永远有效(2.7 后改了)。

Q3:SpringMVC 的执行流程?

标准答:请求 → DispatcherServlet → HandlerMapping 找 Handler+拦截器(HandlerExecutionChain)→ HandlerAdapter 执行 → 返回 ModelAndView → ViewResolver 解析 → 渲染。拦截器三段:preHandle(正向)→ postHandle(逆向)→ afterCompletion(逆向)。

追问链

  • "DispatcherServlet 九大组件?" → HandlerMapping/HandlerAdapter/ViewResolver 是核心三件,还有 Multipart/Locale/Theme/Exception 等
  • "拦截器三个回调时机?" → preHandle 在 Handler 前、postHandle 在 Handler 后视图前、afterCompletion 在视图后(总会执行)
  • "参数绑定做了什么?" → 类型转换、格式化、校验、HttpMessageConverter(JSON↔对象)

常见误解:❌ 以为请求直接找 Controller;❌ 以为 postHandle 一定执行(preHandle 返回 false 时不执行)。

Q4:Spring 事务为什么失效?

标准答@Transactional 基于 AOP 动态代理,失效都是因为「没走代理」或「异常不满足回滚规则」:

  1. 同类自调用(绕过代理)
  2. 非 public 方法
  3. 异常被 catch 吞掉
  4. Checked 异常(默认只回滚 RuntimeException/Error)
  5. 数据库引擎不支持事务(MyISAM)

追问链

  • "自调用怎么解决?" → 拆到不同 Bean,或注入自身代理/AopContext
  • "默认什么异常回滚?" → RuntimeException + Error;Checked 需 rollbackFor
  • "异常吞掉怎么补救?" → 手动 setRollbackOnly()

常见误解:❌ 以为加了注解就一定生效;❌ 以为抛异常就回滚(Checked 不回滚)。

Q5:@Autowired 和 @Resource 区别?

标准答:@Autowired 是 Spring 的,**按类型(byType)**注入,多个同类型再按名称 + @Qualifier;@Resource 是 JSR-250 标准,**按名称(byName)**优先,找不到再 byType。

追问链

  • "接口有多个实现怎么注入?" → @Autowired 配 @Qualifier 指定,或 @Resource(name=...)
  • "required 属性?" → @Autowired(required=false) 可允许为空

常见误解:❌ 以为 @Autowired 按名称注入。

Q6:Bean 的生命周期和循环依赖?

标准答(衔接 [Spring IOC容器初始化与循环依赖](./Spring IOC容器初始化与循环依赖)):Bean 生命周期 = 实例化 → 属性填充 → 初始化(Aware/BeanPostProcessor)→ 使用 → 销毁。循环依赖靠三级缓存解决:singletonObjects(成品)、earlySingletonObjects(提前暴露)、singletonFactories(三级,存 ObjectFactory),A/B 相互依赖时通过提前暴露半成品 + 代理解决。

追问链

  • "为什么需要三级缓存?" → 二级缓存解决不了 AOP 代理场景,三级存工厂延迟生成代理
  • "构造器循环依赖能解决吗?" → 不能,必须用 @Lazy 或重构

常见误解:❌ 以为构造器注入的循环依赖也能靠三级缓存解决(只能解决 setter/字段注入的)。

关联

最近更新