当前位置: 首页 > news >正文

Spring IOC 控制反转

一句话

IOC 是把对象的创建和依赖管理权从代码里转移到了 Spring 容器,开发者不再手动 new 对象和 set 依赖,而是由容器统一管理并注入。


1. 什么是 IOC

传统方式: UserService service = new UserService(); service.setUserDao(new UserDao()); 自己创建对象,自己管理依赖关系 IOC 方式: @Service public class UserService { @Autowired private UserDao userDao; // 容器自动注入 } 对象的创建和依赖关系交给 Spring 容器管理

​**IOC(Inversion of Control,控制反转)**​:对象创建和依赖管理的权力从代码转移到容器。

​**DI(Dependency Injection,依赖注入)**​:IOC 的具体实现方式,容器自动把依赖"注入"到对象中。


2. 容器核心接口

接口特点场景
BeanFactory最基础接口,getBean,懒加载轻量级场景、嵌入式场景
ApplicationContext扩展接口,启动时预实例化单例,集成事件、国际化、AOP绝大多数项目

ApplicationContext 是 BeanFactory 的子接口,功能更全,实际项目中几乎都用它。


3. 核心组件

BeanDefinition: 描述一个 Bean 怎么创建(class 全路径、scope、属性值、依赖关系) 通过 @ComponentScan、@Bean、@Import 等方式产生 是 Spring 容器管理 Bean 的"图纸" BeanFactoryPostProcessor: 在所有 BeanDefinition 加载完毕后、Bean 实例化之前执行 可以修改 BeanDefinition(比如改属性值、改 scope) 典型实现:PropertySourcesPlaceholderConfigurer(解析 ${} 占位符) BeanPostProcessor: 在 Bean 实例化前后做增强 典型实现:AbstractAutoProxyCreator(AOP 代理就在这里生成) @PostConstruct、@Autowired 注入也通过 BeanPostProcessor 实现

三者的执行顺序:

加载 BeanDefinition → BeanFactoryPostProcessor 修改 BeanDefinition → 实例化 Bean → BeanPostProcessor 前置处理(@PostConstruct) → 初始化 → BeanPostProcessor 后置处理(AOP 代理) → Bean 放入容器

4. 依赖注入三种方式

① 构造器注入(推荐) @Autowired public UserService(UserDao userDao) { ... } 优点:依赖不可变,初始化就完整,适合必需依赖 ② Setter 注入 @Autowired public void setUserDao(UserDao userDao) { ... } 优点:可选依赖,灵活 ③ 字段注入(不推荐但最常用) @Autowired private UserDao userDao; 缺点:无法设为 final,依赖关系不透明,不利于测试

@Autowired是 Spring 的注解,按类型注入。@Resource是 JSR-250 的注解,先按名称再按类型注入。


面试回答模板

"IOC 的核心是把对象创建和依赖管理从代码中转移到了 Spring 容器。 开发者通过 @Service、@Component 等注解声明 Bean, 通过 @Autowired 或构造器注入依赖, 容器负责实例化、组装和管理 Bean 的完整生命周期。 容器有两个核心接口:BeanFactory 是最基础的 getBean 接口, ApplicationContext 是扩展接口,支持事件、国际化、AOP。 容器内部通过 BeanDefinition 描述 Bean 的创建方式, BeanFactoryPostProcessor 在实例化前修改定义, BeanPostProcessor 在实例化后做增强,AOP 代理就是在这一步生成的。"

参考来源

  • Day11-Spring 与 SpringBoot
  • 01_Raw【原始素材】/notion 资料/Notion/任务/Spring底层核心原理解析.md
http://www.jsqmd.com/news/1191720/

相关文章:

  • Rage(PC) Modding Notes Rage模组制作 指南 二
  • 万亿后市场的“油转电”:2026年,传统汽修厂如何接住新能源的“三电维修”红利?
  • C++从零解析SHP文件:手写GIS引擎核心,告别GDAL依赖
  • Unity UI粒子渲染性能优化:从RenderTexture到ECS的三大实战技巧
  • C++并发编程:深入理解std::atomic原子操作原理与实战应用
  • C# async、await异步语法 +Async+Task实现斐波那契数列渲染案例
  • 05-04-YooAsset源码-Unity资源定位系统
  • UE5 Niagara系统实战:从零打造动态烟雾特效的完整指南
  • 探秘ARM Cortex-M系列架构——从M0到M7的演进与选型
  • 国科GK7205V300替代海思HI3516EV300:从硬件兼容到软件迁移的完整指南
  • DS90UB662-Q1多路视频流合并:CSI-2转发模式详解与工程实践
  • Cluade 必备技能 Code-Simplifier
  • 【Java踩坑笔记】44_数据库字段用保留字,MyBatis生成的SQL直接报错
  • 【ChatGPT定价策略深度解密】:20年SaaS产品老兵拆解OpenAI 5次调价背后的成本模型、客户分层与ARPU阈值
  • 五次方程的OSOS结构识别与三次枢纽方程剥离方法
  • 从标准到应用:AVS3与H.265/HEVC视频编解码技术深度对比
  • 【Redis八股|第10篇】Spring Boot 项目整合 Redis 实战
  • C++跨平台剪贴板操作:纯头文件实现与多系统API详解
  • 从《论新阶段》到“活的灵魂”:毛泽东思想核心要义与当代技术创新的思想启迪
  • C++ WinInet实现高效HTTP文件下载:断点续传与多线程优化
  • 2026年7月最新嘉兴美度官方售后客服电话及服务网点地址查询 - 亨得利钟表维修中心
  • WorkBuddy 连接百度网盘:能查能上传,但别指望 AI 帮你下载
  • AWR1843BOOST毫米波雷达在自动泊车系统中的优势与实现
  • 影刀RPA 影刀中的SQL查询大全:从简单查询到多表联查
  • Midscene.js框架(5):测试报告系统与调试技巧
  • 第二章 温度、热量与能量(四)---焓
  • 为什么你的Claude脚本总要人工重写?深度拆解Prompt熵值与代码可执行性之间的3个数学阈值(基于217个真实case统计)
  • 从GESP五级真题解析C++算法思维:有趣的数字和问题
  • 模型监控仪表盘实战:从数据漂移到服务延迟的五维健康监测
  • Cocos Creator 3.8.6 游戏快速上架微信小游戏全流程实战指南