第一部分:Spring 的灵魂——IoC 与 AOP
如果把 Spring 比作一个公司,IoC 就是“人力资源部”,而 AOP 就是“行政/审计部”。
1. IoC(控制反转):不再自己造轮子
IoC 的核心思想是:将对象的创建、配置和生命周期管理交给容器。开发者只需通过依赖注入(DI)使用对象。
优点:解耦。对象之间不再直接持有强引用,而是由容器动态注入。
设计模式:工厂模式、单例模式。
2. AOP(面向切面编程):优雅的“业务增强”
AOP 解决了代码重复的问题(如日志记录、性能监控、事务管理)。它将非业务逻辑从业务代码中剥离出来,封装成“切面”。
核心实现:
JDK 动态代理:要求目标类必须实现接口。
CGLIB 代理:通过生成目标类的子类来实现代理,不需要接口。
第二部分:Bean 的一生——生命周期全链路分析
面试官最爱问:“Bean 是怎么从配置变成对象的?”
1. 核心五阶段
实例化 (Instantiate):通过反射创建对象。
属性赋值 (Populate):注入
@Autowired的依赖。初始化 (Initialization):
执行
Aware接口方法。执行
BeanPostProcessor的前置处理。执行
@PostConstruct或init-method。执行
BeanPostProcessor的后置处理(AOP 代理通常在此处生成)。
使用中 (Ready to Use)。
销毁 (Destruction):执行
@PreDestroy或destroy-method。
✍️ 第三部分:大厂高频——三级缓存与循环依赖
如果你能清晰讲出三级缓存,面试官会对你刮目相看。
1. 什么是循环依赖?
A 依赖 B,B 依赖 A。
2. 三级缓存的作用
一级缓存 (singletonObjects):存放完全初始化好的单例 Bean。
二级缓存 (earlySingletonObjects):存放半成品的 Bean(仅实例化,未属性填充)。
三级缓存 (singletonFactories):存放 ObjectFactory,用于处理 AOP 情况下的 Bean 暴露。
核心逻辑:利用三级缓存,提前暴露 Bean 的引用,从而解决 setter 注入下的循环依赖。注意:构造器注入的循环依赖无法解决。
✍️ 第四部分:Spring 事务——不仅是加个注解
1. 事务传播行为(7 种)
最常用的三种:
REQUIRED (默认):如果当前有事务,加入;没有则新建。
REQUIRES_NEW:强制新建事务,挂起当前事务。
NESTED:嵌套事务(子事务回滚不影响父事务,父事务回滚则全回滚)。
2. 💡 实战案例:事务失效的坑
面试中常问:“为什么我加了@Transactional,报错了却不回滚?”
Java
@Service public class OrderService { @Autowired private OrderMapper orderMapper; // 失效场景:方法自调用 public void createOrder(Order order) { // 直接调用本类方法,不走代理对象,事务注解失效! this.saveData(order); } @Transactional public void saveData(Order order) { orderMapper.insert(order); throw new RuntimeException("模拟异常"); } }解决方案:通过注入自己(Self-Injection)或使用AopContext.currentProxy()调用。
第五部分:Spring Boot 自动装配原理
Spring Boot 成功的关键在于“约定优于配置”。
1.@SpringBootApplication的秘密
它是三个注解的组合:
@SpringBootConfiguration@ComponentScan@EnableAutoConfiguration(核心)
2. 执行流程
启动时寻找
META-INF/spring.factories(旧) 或META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(新)。加载候选配置类。
根据
@Conditional条件注解(如@ConditionalOnClass)判断是否真正加载该配置。
第六部分:Spring 面试复盘脑图
Code snippet
mindmap root((Spring 核心知识树)) IoC 与 AOP IoC: 依赖注入, 容器管理, 解耦 AOP: 动态代理(JDK/CGLIB), 切面, 通知 Bean 体系 作用域: Singleton, Prototype, Request, Session 生命周期: 实例化->属性赋值->初始化->销毁 循环依赖: 三级缓存机制 事务管理 传播行为: REQUIRED, REQUIRES_NEW, NESTED 失效场景: 非public, 自调用, 异常类型不匹配 Spring Boot 自动装配: @EnableAutoConfiguration, spring.factories 启动流程: 准备环境, 创建容器, 刷新容器 Spring MVC 核心组件: DispatcherServlet, HandlerMapping, ViewResolver
第七部分:大厂面试官的“夺命连环炮”
BeanFactory 和 ApplicationContext 有什么区别?
回答要点:BeanFactory 是基础接口,懒加载;ApplicationContext 是高级子接口,支持国际化、事件发布,且启动时即加载所有单例 Bean。
Spring 是如何保证单例 Bean 的线程安全的?
回答要点:Spring 本身不保证。如果 Bean 是有状态的(如成员变量),需要开发者使用 ThreadLocal 或改为 Prototype。
如果我有两个同类型的 Bean,Spring 怎么注入?
回答要点:先按类型找,再按名称匹配。可以通过
@Qualifier指定,或@Primary设置优先级。
结语:从“春天”到“架构”
在 10 年的后端生涯中,我见过太多的框架兴衰,但 Spring 始终如一。掌握 Spring,本质上是在掌握 Java 的设计模式与工程实践。
这篇文章梳理了 Spring 面试的每一个核心触点。如果你能结合这些知识点并谈谈你在项目中如何解决“多数据源切换”或“自定义 Starter”的经验,Offer 就在眼前。