05-框架篇面试题(Spring / SpringMVC / SpringBoot)
对应原始资料:
12-BAT/04-框架篇
一、Spring IoC
Q1:IoC 和 DI 的区别
- IoC:控制反转,对象创建权交给 Spring 容器。
- DI:依赖注入,容器在运行时把依赖注入对象(构造/setter/字段)。
Q2:Bean 的生命周期(核心 7 步)
- 实例化(构造方法)。
- 属性赋值(DI)。
- Aware 回调。
- BeanPostProcessor.before。
- 初始化(@PostConstruct / InitializingBean / init-method)。
- BeanPostProcessor.after —— AOP 代理在这里生成。
- 销毁(@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(修饰符 返回值 包.类.方法(参数))、@annotation、within、bean。
Q11:同一个类中方法 A 调 B,B 上的 AOP 失效吗
失效。因为 this.B() 不走代理对象。 解决:从容器拿自己(applicationContext.getBean())或用 AopContext.currentProxy()。
三、Spring 事务
Q12:@Transactional 失效场景(高频)
- 方法非 public。
- 同类内部方法调用(不走代理)。
- 异常被 try-catch 吞掉。
- 抛出检查异常默认不回滚(需
rollbackFor = Exception.class)。 - 类不是 Spring Bean。
- 数据库引擎不支持事务。
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 启动流程
SpringApplication.run启动。- 创建 SpringApplication 实例,推断应用类型。
- 准备环境(读 yml/properties)。
- 创建 ApplicationContext。
- refreshContext:实例化 Bean、自动配置、启动 Tomcat。
- 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 动态代理。