Skip to content

05-框架篇面试题(Spring / SpringMVC / SpringBoot)

对应原始资料:12-BAT/04-框架篇

一、Spring IoC

Q1:IoC 和 DI 的区别

  • IoC:控制反转,对象创建权交给 Spring 容器。
  • DI:依赖注入,容器在运行时把依赖注入对象(构造/setter/字段)。

Q2:Bean 的生命周期(核心 7 步)

  1. 实例化(构造方法)。
  2. 属性赋值(DI)。
  3. Aware 回调。
  4. BeanPostProcessor.before。
  5. 初始化(@PostConstruct / InitializingBean / init-method)。
  6. BeanPostProcessor.after —— AOP 代理在这里生成。
  7. 销毁(@PreDestroy / DisposableBean / destroy-method)。

Q3:Bean 作用域

singleton(默认)、prototype、request、session、application、websocket。

Q4:Bean 是单例的吗

默认是。prototype 每次返回新实例。

Q5:循环依赖怎么解决

  • 三级缓存:singletonObjects(成品)、earlySingletonObjects(半成品)、singletonFactories(ObjectFactory)。
  • A 实例化后提前暴露 ObjectFactory,B 拿到半成品 A,A 完成后放一级缓存。
  • 只能解决 setter 单例循环依赖,构造方法循环依赖无法解决

Q6:三级缓存为什么是三级(不是二级)

第二级缓存能解决普通循环依赖,第三级是为了处理"AOP 提前生成代理对象"——通过 ObjectFactory 决定是否需要生成代理。

二、Spring AOP

Q7:AOP 术语

切面 Aspect、连接点 JoinPoint、切入点 Pointcut、通知 Advice、织入 Weaving。

Q8:通知类型

@Before、@AfterReturning、@Around、@AfterThrowing、@After。

Q9:AOP 底层

  • 有接口:JDK 动态代理。
  • 无接口:CGLIB。
  • SpringBoot 2.x+ 默认 CGLIB。

Q10:切入点表达式

execution(修饰符 返回值 包.类.方法(参数))@annotationwithinbean

Q11:同一个类中方法 A 调 B,B 上的 AOP 失效吗

失效。因为 this.B() 不走代理对象。 解决:从容器拿自己(applicationContext.getBean())或用 AopContext.currentProxy()

三、Spring 事务

Q12:@Transactional 失效场景(高频)

  1. 方法非 public。
  2. 同类内部方法调用(不走代理)。
  3. 异常被 try-catch 吞掉。
  4. 抛出检查异常默认不回滚(需 rollbackFor = Exception.class)。
  5. 类不是 Spring Bean。
  6. 数据库引擎不支持事务。

Q13:事务传播行为

REQUIRED(默认)、REQUIRES_NEW、SUPPORTS、NESTED、MANDATORY、NEVER、NOT_SUPPORTED。

四、SpringMVC

Q14:请求处理流程

浏览器 → DispatcherServlet → HandlerMapping → HandlerAdapter → Controller → ViewResolver/MessageConverter → 响应。

Q15:@Controller vs @RestController

@RestController = @Controller + @ResponseBody(返回数据而非视图)。

Q16:拦截器 vs 过滤器

  • Filter 是 Servlet 规范,拦所有请求。
  • Interceptor 是 SpringMVC 的,只拦 Controller 方法。
  • 执行顺序:Filter → DispatcherServlet → Interceptor.preHandle → Controller → Interceptor.postHandle → 视图渲染 → Interceptor.afterCompletion → Filter。

五、SpringBoot

Q17:自动配置原理

@SpringBootApplication 包含 @EnableAutoConfiguration,通过 AutoConfigurationImportSelector 加载 META-INF/spring.factories(2.x)或 imports 文件(3.x)中的 xxxAutoConfiguration,每个配置类用 @Conditional 判断是否生效。

Q18:SpringBoot 启动流程

  1. SpringApplication.run 启动。
  2. 创建 SpringApplication 实例,推断应用类型。
  3. 准备环境(读 yml/properties)。
  4. 创建 ApplicationContext。
  5. refreshContext:实例化 Bean、自动配置、启动 Tomcat。
  6. afterRefresh、CommandLineRunner 执行。

Q19:内嵌 Tomcat 原理

SpringBoot 内嵌 Tomcat,启动时通过 TomcatServletWebServerFactory 创建 Tomcat 实例并注册 DispatcherServlet。

Q20:如何切换 web 服务器

排除 tomcat starter,引入 undertow / jetty。

六、MyBatis

Q21:#{} 和 ${} 区别

  • #{} 预编译 ?,防注入。
  • ${} 字符串拼接,仅用于动态表名/列名。

Q22:MyBIS 一级 / 二级缓存

  • 一级:SqlSession 级别,默认开。
  • 二级:Mapper 级别,需开启,跨 session 共享。整合 Spring 后基本失效(sqlSession 不一致)。

Q23:MyBatis 接口为什么不需要实现类

Mapper 代理:MyBatis 用 JDK 动态代理生成代理对象,根据 namespace + id 找到对应 SQL 执行。

高频考点速记

  • IoC = 控制反转,DI = 注入。
  • Bean 生命周期 7 步,AOP 代理在 after 阶段。
  • 循环依赖用三级缓存(关键第三级为 AOP 代理)。
  • @Transactional 失效六大场景。
  • DispatcherServlet 是 SpringMVC 核心。
  • SpringBoot 自动配置 = starter + @Conditional + xxxAutoConfiguration。
  • MyBatis #{} 防注入,Mapper 用 JDK 动态代理。