Spring框架概述 + IoC(控制反转)深度理解
(2025最新版,面试+实战双精华,建议收藏)
一、Spring框架概述(3分钟讲完,让面试官点头)
| 项目 | 内容 |
|---|---|
| 是什么 | Spring 是目前全球使用量最大的 Java 企业级应用开发框架,号称“Java 后端的 Android”(生态最完善) |
| 诞生时间 | 2003年,由 Rod Johnson 创立,2004年发布 1.0 |
| 当前最新版本 | Spring Framework 6.2.x(2025年12月) Spring Boot 3.3.x(主流) |
| 基线要求 | Java 17+,Jakarta EE 9+(彻底抛弃 javax.* 包) |
| 核心思想(2个词) | 1. IoC(控制反转 / 依赖注入) 2. AOP(面向切面编程) |
| 最大贡献 | 把原来重量级、配置繁琐的 EJB(Java EE)干掉,成就了“轻量级”“约定大于配置”的新时代 |
| 市场占有率 | 国内 95%+ 的互联网公司后端都用 Spring Boot,全球企业级 Java 项目 70%+ 使用 Spring 系列 |
| 生态圈(2025年) | Spring Boot → Spring Cloud → Spring Security → Spring Data → Spring Batch → Spring AI … |
一句话总结:
学 Java 后端 = 学 Spring Boot,学不会 Spring 基本等于不会现代 Java 企业开发。
二、IoC(Inversion of Control)最通俗、最深入的理解
1. IoC 到底在反转什么?
| 传统方式(没有 IoC) | Spring IoC 方式 |
|---|---|
| 程序员自己 new 对象 | 程序员只管用,对象谁来 new?→ 交给 Spring 容器 |
| 控制权在程序员手里 | 控制权“反转”给了 Spring 容器 |
| 依赖关系写死在代码里 | 依赖关系外部化配置(注解或 XML) |
| 想换实现要改代码 | 想换实现只改配置,代码零改动 |
举个最经典的例子:
// 没有 IoC —— 你自己掌控一切
public class OrderService {
private PaymentService pay = new AliPayService(); // 硬编码死了!
}
// 有 IoC —— 控制权交给 Spring
@Service
public class OrderService {
@Autowired
private PaymentService pay; // 我只说我要一个 PaymentService,具体是阿里还是微信我不管!
}
→ 控制权从“程序员自己 new”反转成了“容器帮我 new”,这就是 Inversion of Control。
2. IoC 的另一种名字:DI(依赖注入 Dependency Injection)
Martin Fowler 说:“IoC 太抽象了,叫 DI 更准确”。
官方结论:IoC 是设计思想,DI 是实现方式,现在大家基本把两者等同使用。
三种注入方式对比(面试必问):
| 注入方式 | 示例 | 优点 | 缺点 | 推荐指数 |
|---|---|---|---|---|
| 构造器注入 | @Autowired public Xxx(A a, B b) | 强制依赖、不可变、便于测试 | 参数多时代码臃肿 | ★★★★★ |
| Setter 注入 | @Autowired public void setX(X x) | 灵活、可选依赖、支持循环依赖 | 可被外部随意修改 | ★★★ |
| 字段注入 | @Autowired private Xxx xxx; | 代码最简洁 | 无法 final、测试困难、隐藏依赖 | ★★ |
2025年主流建议:优先构造器注入(Lombok @RequiredArgsConstructor 更优雅)
3. Spring IoC 容器家族(面试常画图)
BeanFactory(老祖宗,基本没人用)
↑
ApplicationContext(99.99% 项目用的都是它)
├── ClassPathXmlApplicationContext(XML时代,已淘汰)
├── FileSystemXmlApplicationContext(同上)
├── AnnotationConfigApplicationContext(当前主流,纯注解)
└── WebApplicationContext(Web项目专用)
4. 一个 Bean 是怎么诞生的?(11步生命周期,面试画图必备)
- 实例化(new 一个空对象)
- 填充属性(依赖注入)
- Aware 系列回调(BeanNameAware、ApplicationContextAware 等)
- BeanPostProcessor 前置处理
- @PostConstruct
- InitializingBean.afterPropertiesSet()
- init-method
- BeanPostProcessor 后置处理 → 这里生成 AOP 代理!
- 放入单例池,可以使用了
- @PreDestroy
- DisposableBean.destroy() → destroy-method → 销毁
5. 经典面试题速答
| 问题 | 标准答案 |
|---|---|
| Spring Bean 默认作用域? | singleton(单例) |
| Spring 是如何解决循环依赖的? | 三级缓存 + 提前暴露“半成品对象”(ObjectFactory) |
| 构造器注入能解决循环依赖吗? | 不能!因为构造器阶段对象还没创建完就卡住了 |
| @Autowired 是按类型还是按名字注入? | 先 byType,再 byName(@Qualifier 可指定名字) |
| @Component @Service @Repository 区别? | 都是 @Component,只是语义不同,@Repository 还有翻译异常功能 |
三、2025年最新一句话总结 IoC
“以前是我自己谈恋爱(自己 new 对象),现在是相亲网站(Spring 容器)给我介绍对象,我只提要求(接口),具体是谁我不管,离了婚(换实现)也只用改网站资料(配置),不影响我本人(业务代码)。”
记住这套说法 + 11步生命周期图 + 三级缓存,Spring IoC 部分面试基本无敌!
需要我继续讲:
- AOP 原理
- Spring Boot 自动配置原理
- 循环依赖三级缓存源码
- 手写简化版 IoC 容器
直接说你要哪个,我立刻给你最详细的版本!