【Spring】超详细!一篇文章让你完全理解Spring Ioc和 DI 📅 发布时间:2026/7/11 22:24:47 👁️ 浏览次数: 【Spring】超详细一篇文章让你完全理解 Spring IoC 和 DI大家好我是 Grok。今天我们来聊聊 Spring 框架的核心灵魂——IoCInversion of Control控制反转和DIDependency Injection依赖注入。如果你是 Spring 小白或者想彻底搞懂这两个概念这篇文章绝对够用我们从基础原理入手逐步深入到实际代码、配置和高级玩法保证逻辑清晰、易记。为什么说“超详细”因为我会用通俗比喻像“厨师 vs 餐厅老板”来解释抽象概念。表格对比快速区分传统方式 vs Spring 方式。代码示例Maven Java 简单项目复制就能跑。步骤拆解从 XML 配置到注解、Java 配置全覆盖。常见坑避免初学者踩雷。假设你有 Java 基础类、接口、Maven没问题就开始吧第一部分基础概念——IoC 和 DI 到底是什么1.1 IoC控制反转Inversion of Control传统编程你程序员像个“厨师”自己控制一切——创建对象、调用方法、管理依赖。比如你要一个“汽车”对象就自己new Car()然后自己组装轮子、引擎。IoC 的核心思想把“控制权”反转给别人Spring 容器。你不再自己new对象而是告诉 Spring“我需要一个汽车”Spring 像“餐厅老板”一样自动帮你组装好、注入依赖、甚至管理生命周期。为什么需要 IoC传统方式耦合太紧改一个类就得改一堆地方。IoC 解耦让代码更灵活、可测试、可扩展。IoC 的好处3 大关键词解耦模块间不直接依赖改动不连锁反应。复用对象像“乐高积木”随时组装。管理Spring 统一管理对象创建、销毁、作用域。IoC 是“思想”DI 是“实现方式”。IoC 就像“外卖平台”DI 就像“骑手送餐”。1.2 DI依赖注入Dependency InjectionDI 是 IoC 的具体实现Spring 不是让你自己找依赖而是“注入”给你。依赖什么一个对象需要另一个对象才能工作。比如Car需要Engine和Wheel。注入怎么做Spring 通过配置XML/注解/Java自动把依赖“塞”进你的对象。DI 的 3 种方式按注入时机分方式描述优点/缺点示例场景构造函数注入通过构造方法注入依赖强制依赖对象创建时就注入测试友好核心依赖如数据库连接Setter 注入通过 Setter 方法注入灵活可选依赖但可能注入不全可选配置如日志级别接口注入通过接口方法注入较少用动态但复杂遗留系统集成DI 让你的代码从“主动拉取”依赖变成“被动接收”。1.3 IoC vs DI 的关系别混淆IoC 是大概念控制反转包括 DI 和其他如 AOP。DI 是 IoC 的子集具体怎么反转控制通过注入依赖。Spring 的 IoC 容器ApplicationContext或BeanFactory管理所有 Bean对象。一句话IoC 是“老板指挥”DI 是“老板给你发工具”。第二部分Spring 中的 IoC 和 DI 实战Spring 版本假设用 Spring Boot 2.7 或 Spring Framework 6.x2026 年主流。先建个 Maven 项目!-- pom.xml 核心依赖 --dependenciesdependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion6.0.0/version!-- 最新版自行替换 --/dependency/dependencies2.1 配置方式 1XML 配置经典但老派XML 是 Spring 最早的配置方式适合理解底层。步骤拆解定义 BeanXML 文件中声明对象。注入依赖用property或constructor-arg。获取容器ClassPathXmlApplicationContext加载 XML。示例代码接口和类publicinterfaceEngine{voidstart();}publicclassPetrolEngineimplementsEngine{publicvoidstart(){System.out.println(Petrol Engine started);}}publicclassCar{privateEngineengine;// 依赖// Setter 注入publicvoidsetEngine(Engineengine){this.engineengine;}publicvoiddrive(){engine.start();System.out.println(Car is driving);}}XML 配置applicationContext.xml?xml version1.0 encodingUTF-8?beansxmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd!-- 定义 Bean --beanidpetrolEngineclasscom.example.PetrolEngine/beanidcarclasscom.example.Car!-- DISetter 注入 --propertynameenginerefpetrolEngine//bean/beans测试publicclassMain{publicstaticvoidmain(String[]args){ApplicationContextcontextnewClassPathXmlApplicationContext(applicationContext.xml);Carcar(Car)context.getBean(car);// IoC 容器提供car.drive();// 输出: Petrol Engine started \n Car is driving}}构造函数注入版 XML替换propertybeanidcarclasscom.example.Carconstructor-argrefpetrolEngine//beanCar 类加构造public Car(Engine engine) { this.engine engine; }2.2 配置方式 2注解配置现代主流简单从 Spring 2.5 开始注解取代 XML。Spring Boot 默认用这个。关键注解注解作用示例Component标记类为 Bean通用Component public class Car {}Service业务层 BeanServiceRepositoryDAO 层 BeanRepositoryControllerWeb 层 BeanControllerAutowired自动注入依赖byType默认Autowired private Engine engine;Qualifier指定 Bean 名当多个同类型时Qualifier(“petrol”)Configuration配置类代替 XMLConfiguration public class AppConfig {}Bean方法返回 BeanBean public Engine engine() {}ComponentScan扫描包自动发现 BeanComponentScan(“com.example”)示例代码注解版类ComponentpublicclassPetrolEngineimplementsEngine{publicvoidstart(){System.out.println(Petrol Engine started);}}ComponentpublicclassCar{AutowiredprivateEngineengine;// DI 注入publicvoiddrive(){engine.start();System.out.println(Car is driving);}}配置类可选如果不扫描默认包ConfigurationComponentScan(com.example)// 扫描包publicclassAppConfig{}测试publicclassMain{publicstaticvoidmain(String[]args){ApplicationContextcontextnewAnnotationConfigApplicationContext(AppConfig.class);Carcarcontext.getBean(Car.class);car.drive();}}自动装配模式Autowired 的底层byType按类型匹配默认。byName按 Bean 名匹配用 Qualifier。2.3 配置方式 3Java 配置纯代码零 XML/注解污染适合大型项目配置集中。示例基于 2.2 的类去掉 ComponentConfigurationpublicclassAppConfig{BeanpublicEngineengine(){returnnewPetrolEngine();}BeanpublicCarcar(){CarcnewCar();c.setEngine(engine());// 手动 DIreturnc;}}测试同上new AnnotationConfigApplicationContext(AppConfig.class)。第三部分高级玩法——Bean 管理和优化3.1 Bean 作用域Scope默认 Singleton单例但可以改。Scope描述注解/配置singleton全局唯一实例默认prototype每次 getBean 都新创建Scope(“prototype”)request每个 HTTP 请求一个Scope(“request”) (Web)session每个会话一个Scope(“session”)示例Scope(prototype) public class Car {}3.2 Bean 生命周期IoC 容器管理从创建到销毁的全过程实例化new。属性注入DI。初始化PostConstruct 或 init-method。使用。销毁PreDestroy 或 destroy-method。自定义publicclassCar{PostConstructpublicvoidinit(){System.out.println(Init);}PreDestroypublicvoiddestroy(){System.out.println(Destroy);}}3.3 自动装配AutowiringEnableAutoConfigurationSpring Boot 用自动配置常见 Bean如 DataSource。问题多个同类型 Bean用 Primary 标记首选或 Qualifier 指定。第四部分常见问题 踩坑指南问题/坑原因解决NoSuchBeanDefinitionExceptionBean 未定义或未扫描检查 Component / Bean / 扫描包UnsatisfiedDependencyException依赖未注入检查 Autowired / 类型匹配循环依赖A 依赖 BB 依赖 A用 Setter 注入 / Lazy 延迟XML vs 注解性能XML 解析慢优先注解 / Java 配置测试时注入失败上下文未加载用 SpringBootTest调试技巧日志级别调到 DEBUG看 Spring 如何装配 Bean。第五部分总结 扩展学习核心回顾IoC 是反转控制DI 是注入依赖。Spring 通过容器ApplicationContext管理 Bean实现解耦和灵活。为什么 Spring 牛因为 IoC/DI 让大型项目像“积木”一样搭建易维护。下一步学 AOP切面编程然后 Spring Boot简化版 Spring。练习建议建个小项目注入 Service 到 Controller模拟用户注册。如果你有具体代码问题、或想看 Spring Boot 版示例继续问我比如“帮我写个带数据库的 DI 示例”
收藏备用|2026年AI大模型学习指南(小白+程序员必看,避坑+实操全干货) 最近很多朋友私信问我:“2026年想提升技术,选什么方向最有前景、最容易落地?” 我的回答从来都是一致的——AI大模型。其实我刚入门时,也是个跨行零基础的纯小白,没有系统教程、没有行业资源,全靠摸索和前辈… 2026/7/11 22:22:47
收藏备用|小白程序员必看!RAG技术详解,轻松搞定大模型“胡说八道”难题 本文专为小白程序员和大模型入门者打造,详细拆解RAG(检索增强生成)技术核心,通过“检索生成”的双重逻辑,彻底解决传统AI最让人头疼的“幻觉问题”(也就是常说的“胡说八道”)。RAG核心分为三大… 2026/7/4 20:45:45
亚马逊,速卖通采购告别砍单封号:破解四大核心环境难题 在自行进行养号进行采购及测评的领域中,拥有一个稳定可靠的环境系统是开启成功的首要条件。环境系统犹如地基,为后续的各项操作提供稳固支撑。常见环境系统方案深度解析 在自养号测评采购中,环境系统的选择至关重要。早期,虚拟机、… 2026/7/11 10:08:08
AI 搜索排名 在当今数字化时代,AI搜索已逐渐成为主流流量入口,企业要想在激烈的市场竞争中脱颖而出,占据有利的AI搜索排名至关重要。今天,就让我们深入探讨AI搜索排名的重要性、企业面临的痛点以及如何借助专业力量实现逆袭。企业的痛点&#… 2026/7/11 22:22:50
UE4控制台实战:性能监控、高保真截图与图形调试核心命令详解 1. 项目概述:从性能监控到高保真截图,UE4控制台的实战价值在虚幻引擎4(UE4)的开发与调试过程中,控制台命令是开发者手中一把极其锋利且高效的“瑞士军刀”。很多刚接触UE4的朋友,可能觉得控制台只是一个输入… 2026/7/11 22:22:50
微信小程序下拉刷新 3 种实现方案对比:原生 vs scroll-view vs 第三方组件 微信小程序下拉刷新3种实现方案深度对比与选型指南在小程序开发中,下拉刷新已成为提升用户体验的关键交互设计。面对不同业务场景,开发者常陷入技术选型困境:是使用原生方案快速实现,还是采用scroll-view获得更多控制权࿰… 2026/7/11 22:16:49
如何用Umi-OCR实现高效文档数字化:从入门到精通的完整指南 如何用Umi-OCR实现高效文档数字化:从入门到精通的完整指南 【免费下载链接】Umi-OCR OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片,PDF文档识别,排除水印/页眉页脚,扫描/生成二维码。内置多国… 2026/7/11 22:16:49
为什么选择aops-vulcanus?OpenEuler运维工具库的7大优势 为什么选择aops-vulcanus?OpenEuler运维工具库的7大优势 【免费下载链接】aops-vulcanus A basic tool libraries of aops, including logging, configure and response, etc. 项目地址: https://gitcode.com/openeuler/aops-vulcanus 前往项目官网免费下载&… 2026/7/11 22:14:48
etipc核心功能解析:如何实现高效的多播通信增强 etipc核心功能解析:如何实现高效的多播通信增强 【免费下载链接】etipc enhanced tipc 项目地址: https://gitcode.com/openeuler/etipc 前往项目官网免费下载:https://ar.openeuler.org/ar/ etipc(enhanced tipc)作为ope… 2026/7/11 22:12:48
5分钟搞定Kodi字幕难题:智能字幕插件让你追剧无忧 [特殊字符] 5分钟搞定Kodi字幕难题:智能字幕插件让你追剧无忧 🎬 【免费下载链接】zimuku_for_kodi Kodi 插件,用于从「字幕库」网站下载字幕 项目地址: https://gitcode.com/gh_mirrors/zi/zimuku_for_kodi 还记得那个深夜吗?你刚下载… 2026/7/11 0:00:11
工业信号干扰处理与FOD4216光耦应用实战 1. 工业环境中的信号干扰挑战在工业自动化领域,信号采集的准确性直接关系到整个控制系统的可靠性。典型的工业现场充斥着各种干扰源:大功率电机启停产生的电磁干扰、变频器工作产生的高频噪声、继电器触点火花放电,以及长距离传输引入的共模干… 2026/7/11 0:00:11
OpenHarmony 完整项目工程整合规范 + 模块化分层架构(API23+ 标准企业级结构) 摘要前面系列教程覆盖了 ArkUI 组件、路由、生命周期、本地存储、网络请求、Ability 底层全套基础能力,本篇统一梳理标准工程目录分层、模块化拆分、代码复用规范、全局工具统一管理、项目打包权限配置、常见工程报错统一解决方案,形成可直接用于课程设计… 2026/7/11 0:00:11
6个月转型AI工程师:实战路径与核心技能 1. 项目概述:6个月转型AI工程师的可行性路径在2023年大模型技术爆发的背景下,AI工程师岗位需求同比增长217%(LinkedIn数据)。不同于传统算法工程师需要3-5年培养周期,现代AI工程师更侧重工程化落地能力。我在硅谷科技公… 2026/7/11 14:53:30
TPAFE0808与PIC18F87K22的多通道信号采集方案 1. 项目背景与核心需求在工业自动化、医疗设备和科研仪器等领域,多通道信号采集与系统监测是基础且关键的技术需求。传统方案往往面临通道数量不足、信号调理复杂、系统集成度低等问题。TPAFE0808作为一款8通道模拟前端芯片,与PIC18F87K22微控制器的组合… 2026/7/11 12:30:52
STC3115与PIC18LF26K80构建高精度电池管理系统 1. STC3115与PIC18LF26K80在电池管理系统中的核心价值在现代电子设备中,电池管理系统(BMS)的重要性不亚于设备的核心处理器。STC3115作为一款高精度电池电量监测IC,与PIC18LF26K80微控制器的组合,构成了一个既能精确监控又能智能管理的完整解… 2026/7/11 15:29:59