Spring核心面试知识点(IoC/Bean生命周期/AOP/事务)
前言
本文为自用复习笔记,核心用于梳理Spring核心高频面试知识点,方便后续回顾、巩固重点,避免遗忘关键细节。
本次笔记将围绕IoC容器启动流程、Bean完整生命周期、AOP代理区别、事务传播机制、事务失效8大场景展开详细剖析。
PS:
最近跳槽复习Java全栈,Spring作为必问模块,必须把底层流程、生命周期、代理机制、事务坑点全部吃透,这份笔记适合突击背诵。
本文根据自己整理与AI生成部分内容相结合。
一、IoC 容器启动流程(核心必背)
1.1 整体流程概述
Spring IoC 启动就是加载配置 → 扫描Bean → 创建Bean → 初始化Bean → 完成容器就绪 的全过程。
核心入口:ApplicationContext 的 refresh() 方法。
1.2 详细启动步骤
-
准备刷新
设置启动状态、激活配置文件、初始化环境。
-
加载Bean定义信息
读取XML/注解/JavaConfig,解析出所有Bean的定义信息,存入BeanDefinitionMap。
-
预处理BeanFactory
执行BeanFactoryPostProcessor,可修改Bean定义、注册新Bean。
-
注册BeanPostProcessor
提前实例化后置处理器,为后续Bean初始化做准备。
-
初始化国际化、事件广播器
容器基础组件初始化。
-
提前实例化单例Bean(核心)
遍历BeanDefinition,按依赖顺序实例化 → 属性赋值 → 初始化。
-
** finishRefresh 完成启动**
发布容器就绪事件,启动完成,对外提供服务。
二、Bean 完整生命周期(最常考)
2.1 生命周期总览
Bean生命周期 = 实例化 → 属性填充 → 初始化 → 使用 → 销毁
2.2 详细11步流程(面试满分版)
-
实例化Bean
调用构造方法,创建对象(堆内存分配)。
-
填充属性(依赖注入DI)
@Autowired、@Resource、setter注入,完成依赖赋值。
-
执行Aware接口
依次执行:BeanNameAware、BeanFactoryAware、ApplicationContextAware。
-
前置处理(BeanPostProcessor#postProcessBeforeInitialization)
AOP、注解解析在这里工作。
-
执行初始化方法
执行**@PostConstruct**。
-
执行InitializingBean#afterPropertiesSet。
-
执行自定义init-method。
-
后置处理(BeanPostProcessor#postProcessAfterInitialization)
AOP代理在这里生成。 -
Bean就绪使用
存入单例池(singletonObjects)。
-
销毁前执行
执行**@PreDestroy**。
-
执行销毁方法
DisposableBean、destroy-method。
2.3 一句话速记
实例化 → 赋值 → Aware → 前置 → 初始化 → 后置 → 代理 → 使用 → 销毁
三、AOP JDK动态代理 vs CGLIB 代理
3.1 核心区别(面试必背表格)
| 对比项 | JDK动态代理 | CGLIB代理 |
|---|---|---|
| 实现原理 | 实现接口,生成代理类 | 继承目标类,生成子类 |
| 要求 | 目标类必须实现接口 | 目标类不能被final |
| 代理方式 | 接口代理 | 继承代理 |
| 性能 | 低版本慢,JDK8后接近 | 创建快,执行略慢 |
| Spring默认 | 有接口用JDK | 无接口用CGLIB |
| final方法 | 不能代理 | 不能代理 |
3.2 关键结论
- 目标类有接口 → JDK代理
- 目标类无接口 → CGLIB代理
- SpringBoot 2.0以后默认强制CGLIB(可配置改回JDK)
3.3 为什么AOP要在初始化后生成代理?
因为必须等Bean初始化完成、属性注入完毕,才能安全创建代理对象,否则会导致依赖注入失效。
四、Spring 事务传播机制(7种必背)
4.1 核心概念
事务传播机制:多个事务方法相互调用时,事务如何传递、合并、新建。
4.2 7种传播行为(高频3种重点记)
1. REQUIRED(默认)
- 有事务就加入,没有就新建。
- 最常用,业务层默认。
2. REQUIRES_NEW
- 挂起当前事务,新建独立事务。
- 两个事务互不影响,一个回滚不影响另一个。
3. NESTED
- 嵌套事务,主事务回滚则子事务回滚。
- 子事务回滚不影响主事务。
其他4种(了解)
- SUPPORTS:有事务就用,没有就非事务运行。
- NOT_SUPPORTED:非事务运行,挂起事务。
- MANDATORY:必须在事务内运行,否则抛异常。
- NEVER:必须非事务运行,否则抛异常。
4.3 一句话记忆
REQUIRED合并、REQUIRES_NEW独立、NESTED嵌套。
五、事务失效 8 大场景(高频坑点)
1. 方法不是 public
事务代理只拦截 public 方法,private/protected 直接失效。
2. 方法被 final / static 修饰
代理无法重写,无法生成AOP。
3. 自身调用(同类方法互调)
java
@Transactional
public void a() {
// 未经过代理,直接调用目标方法,事务失效
b();
}
public void b() {}
解决:注入自身代理对象调用,或AopContext.currentProxy()。
4. 异常被 try-catch 吃掉
java
try {
// 报错
} catch (Exception e) {
// 没抛出,事务不回滚
}
解决:抛出异常或手动回滚。
5. 抛出非RuntimeException
默认只回滚RuntimeException 和Error 。
解决:rollbackFor = Exception.class。
6. 未被Spring管理(没加@Service/@Component)
没有被IoC管理 → 没有代理 → 事务失效。
7. 多线程调用
新线程不在当前事务上下文,独立执行。
8. 数据库引擎不支持事务
MyISAM不支持事务,必须用InnoDB。
总结(面试速背)
- IoC启动:加载定义 → 扫描 → 预处理 → 实例化单例 → 完成启动。
- Bean生命周期:实例化 → 赋值 → Aware → 前后置 → 初始化 → 代理 → 使用 → 销毁。
- AOP代理:有接口JDK,无接口CGLIB,final无法代理。
- 事务传播:REQUIRED默认合并,REQUIRES_NEW新建独立。
- 事务失效8场景:非public、自身调用、吞异常、非运行时异常、非public、多线程、引擎不支持、没被Spring管理。
需要我帮你把这篇内容生成可直接保存的 .md 文件纯文本吗?