《SpringBoot 3:入门与应用实战》第 2 章 IOC 思想与实现 阅读笔记 2
《SpringBoot 3入门与应用实战》第 2 章 IOC 思想与实现 阅读笔记 22.2 IOC 的两种实现方式了解 IOC 思想的由来之后下面学习 Spring Framework 的 IOC 思想的具体实现。IOC 的实现方式包含两种分别是依赖查找 (Dependency Lookup) 与依赖注入 (Dependency Injection)。2.2.1 依赖查找依赖查找的含义是根据指定的对象名称或对象的所属类型主动从 IOC 容器中获取对应的具体对象后续将这种从 IOC 容器中获取的对象称为 bean 对象​。1.根据名称查找 (byName)(1)创建工程引入依赖(2)编写配置文件Spring Framework 使用 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/beans(3)声明普通类并注册可以创建一个普通的 Person 类其内部不需要编写任何代码。随后在 quickstart-byname.xml 文件中使用 Spring Framework 的定义规则将Person 声明到配置文件中。配置文件的编写方式非常简单使用 标签来声明一个注册到 IOC 容器中的 Bean它的 id 为 “person”​对应的类型就是上面创建的 Person 类。packagecom.yangjunbo.dl.examplea;/** * ClassName: Person * Package: com.yangjunbo.dl.examplea * Description: * * Author 杨钧博 * Create 2026/8/11 16:01 * Version 1.0 */publicclassPerson{}?xml version1.0encodingUTF-8?beans xmlnshttp://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.xsdbean idpersonclasscom.yangjunbo.dl.examplea.Person/bean/beans(4)创建启动类并测试有了配置文件后下一步就是要读取和解析配置文件我们创建一个 QuickstartByNameApplication 类并声明 main 方法编写启动逻辑。读取quickstart-byname.xml 文件的方法有很多因为是第一个示例所以我们选择一种相对简单的方法。简单解释代码的含义。要想读取 quickstart-byname.xml 配置文件需要一个载体来加载示例代码中选择使用ClassPathXmlApplicationContext 来加载可以从当前项目的类路径 (classpath) 下找到 dl 目录下的 quickstart-byname.xml 文件。加载完成后我们使用 BeanFactory 接口来接收该对象多态的思想​。之后从 BeanFactory 中调用 getBean 方法从 IOC 容器中取出名为 “person” 的对象并强制转换为 Person 类型最后打印即可。packagecom.yangjunbo.dl.examplea;importorg.springframework.beans.factory.BeanFactory;importorg.springframework.context.support.ClassPathXmlApplicationContext;publicclassQuickstartByNameApplication{publicstaticvoidmain(String[]args)throwsException{BeanFactoryfactorynewClassPathXmlApplicationContext(dl/quickstart-byname.xml);Personperson(Person)factory.getBean(person);System.out.println(person);}}运行 QuickstartByNameApplication 的 main 方法控制台可以成功打印出 Person 的全限定类名内存地址证明测试方法编写成功。2.根据类型查找 (byType)从上面的示例中可以发现一个问题通过名称获取的 bean 对象类型只能是 Object如果需要精准获取 IOC 容器中某一个类型的 bean 对象则需要根据类型查找。为了演示基于类型查找这次使用 标签声明时我们不再指定 id 属性相应地启动类QuickstartByTypeApplication 中调用 getBean 方法时不再传入字符串变量而是直接传入希望获取的 Bean 的 class 类型而且接收对象不再需要强制类型转换。?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.xsdbeanclasscom.yangjunbo.dl.examplea.Person/bean/beanspackagecom.yangjunbo.dl.examplea;importorg.springframework.beans.factory.BeanFactory;importorg.springframework.context.support.ClassPathXmlApplicationContext;publicclassQuickstartByTypeApplication{publicstaticvoidmain(String[]args){BeanFactoryfactorynewClassPathXmlApplicationContext(dl/quickstart-bytype.xml);Personpersonfactory.getBean(Person.class);System.out.println(person);}}3.接口与实现类基于类型查找时还可以根据接口获取对应的实现类当然这要求实现类已经注册到 IOC 容器中​。将 2.1 节中的 DemoDao 与 DemoDaoImpl复制到 examplea 目录中并在 quickstart-bytype.xml 文件中加入 DemoDaoImpl 的声明定义。随后在启动类 QuickstartByTypeApplication 中使用 BeanFactory 取出 DemoDao并打印 findAll 方法的返回数据。运行 main 方法控制台可以打印出 [aaa, bbb, ccc]​证明 DemoDaoImpl 也成功注入并且 BeanFactory 可以根据接口类型找到对应的实现类。packagecom.yangjunbo.dl.examplea;importjava.util.List;/** * ClassName: DeamDao * Package: com.yangjunbo.dao * Description: * * Author 杨钧博 * Create 2026/8/11 11:53 * Version 1.0 */publicinterfaceDemoDao{ListStringfindAll();}packagecom.yangjunbo.dl.examplea.impl;importcom.yangjunbo.dl.examplea.DemoDao;importjava.util.Arrays;importjava.util.List;/** * ClassName: DemoDaoImpl * Package: com.yangjunbo.dao.impl * Description: * * Author 杨钧博 * Create 2026/8/11 11:57 * Version 1.0 */publicclassDemoDaoImplimplementsDemoDao{OverridepublicListStringfindAll(){returnArrays.asList(aaa,bbb,ccc);}}?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.xsdbeanclasscom.yangjunbo.dl.examplea.Person/beanbeanclasscom.yangjunbo.dl.examplea.impl.DemoDaoImpl//beanspackagecom.yangjunbo.dl.examplea;importorg.springframework.beans.factory.BeanFactory;importorg.springframework.context.support.ClassPathXmlApplicationContext;publicclassQuickstartByTypeApplication{publicstaticvoidmain(String[]args){BeanFactoryfactorynewClassPathXmlApplicationContext(dl/examplea/quickstart-bytype.xml);Personpersonfactory.getBean(Person.class);System.out.println(person);DemoDaodemoDaofactory.getBean(DemoDao.class);System.out.println(demoDao.findAll());}}2.2.2 依赖注入由上面的三个示例中可以发现一个问题以上创建的 bean 对象都是不带属性值的如果我们要创建的 bean 对象需要一些预设的属性那么就要涉及 IOC 的另一种实现依赖注入。1.简单属性值注入为了与依赖查找的对象进行区分我们新创建一个 Person 类并声明两个属性 name 和 age。随后编写 XML 配置文件 inject-set.xml将Person 类注册到 IOC 容器中。packagecom.yangjunbo.di.examplea;publicclassPerson{privateStringname;privateIntegerage;publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.namename;}publicIntegergetAge(){returnage;}publicvoidsetAge(Integerage){this.ageage;}OverridepublicStringtoString(){returnPerson{namename\, ageage};}}?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.xsdbeanidpersonclasscom.yangjunbo.di.examplea.Person/bean/beans如果仅使用上述的代码驱动 IOC 容器初始化那么从 IOC 容器中取出的 Person 对象中 name 与 age 的属性将全部为 null。packagecom.yangjunbo.di.examplea;importorg.springframework.beans.factory.BeanFactory;importorg.springframework.context.support.ClassPathXmlApplicationContext;publicclassQuickstartInjectBySetXmlApplication{publicstaticvoidmain(String[]args)throwsException{BeanFactorybeanFactorynewClassPathXmlApplicationContext(di/examplea/inject-set.xml);PersonpersonbeanFactory.getBean(Person.class);System.out.println(person);}}如果需要给 bean 对象的属性赋值使用的标签是 这个标签有两个属性可以供我们使用分别是 name属性名和 value属性值​。?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.xsdbeanidpersonclasscom.yangjunbo.di.examplea.Personpropertynamenamevaluetest-person-byset/propertynameagevalue18//bean/beans运行 QuickstartInjectBySetXmlApplication 类的 main 方法控制台可以打印 Person 对象的属性值说明依赖注入属性成功。2.关联 bean 对象注入创建一个新的小猫类 Cat并声明 name 和 master 属性分别指代小猫的名字和主人。随后在 inject-set.xml 配置文件中定义一个新的 Beanid 为 “cat”​并使用 标签的另一个属性 ref 引用 IOC 容器中的一个现有的 bean 对象即 person。编写完成后在QuickstartInjectBySetXmlApplication 类中获取 Cat 对象并打印可以发现 Cat 对象中的 master 属性就是上面的 Person 对象关联 bean 对象的依赖注入也实现完成packagecom.yangjunbo.di.examplea;publicclassCat{privateStringname;privatePersonmaster;publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.namename;}publicPersongetMaster(){returnmaster;}publicvoidsetMaster(Personmaster){this.mastermaster;}OverridepublicStringtoString(){returnCat{namename\, mastermaster};}}?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.xsdbeanidpersonclasscom.yangjunbo.di.examplea.Personpropertynamenamevaluetest-person-byset/propertynameagevalue18//beanbeanidcatclasscom.yangjunbo.di.examplea.Catpropertynamenamevaluetest-cat/!-- ref引用上面的person对象 --propertynamemasterrefperson//bean/beanspackagecom.yangjunbo.di.examplea;importorg.springframework.beans.factory.BeanFactory;importorg.springframework.context.support.ClassPathXmlApplicationContext;publicclassQuickstartInjectBySetXmlApplication{publicstaticvoidmain(String[]args)throwsException{BeanFactorybeanFactorynewClassPathXmlApplicationContext(di/examplea/inject-set.xml);PersonpersonbeanFactory.getBean(Person.class);System.out.println(person);CatcatbeanFactory.getBean(Cat.class);System.out.println(cat);}}2.2.3 依赖查找与依赖注入的对比依赖查找是从 Spring 的 IOC 容器中根据 Bean 的名称或类型找到对应的 Bean。依赖注入是 Spring 的 IOC 容器在创建 Bean 的时候对 Bean 中的属性进行赋值。2.3 BeanFactory 与 ApplicationContext2.3.1 理解 IOC 容器顾名思义IOC 容器即实现了 IOC 思想的容器。容器可以理解为“一个具备创建组件并管理组件的区域”​。我们将需要创建的组件的信息以配置文件的方式提供给 Spring Framework在创建 IOC 容器的时候它就会自动帮我们创建这些组件这种从加载和解析配置文件到完成容器和内部组件 (Bean) 的过程就是 IOC 容器的基本处理流程。2.3.2 对比 BeanFactory 与 ApplicationContextBeanFactory 接口提供了一个对象的管理机制ApplicationContext 是 BeanFactory 的子接口它简化了与 AOP 的整合、消息机制、事件机制以及对 Web 环境的扩展WebApplicationContext 等。开发者要使用 ApplicationContext 而不是 BeanFactory。2.3.3 理解 Context 与 ApplicationContextContext 意为“上下文”​简单地说Context 指的是当程序运行到指定代码时可以获取的额外数据和信息。在一篇文章中看到某个故事情节时可能想要分析情节的作用这就需要结合当前阅读的部分及其前后章节来综合分析这里的“前后章节”即上下文也就是 Context。在软件开发中 Context 通常可以理解为我们编写的代码执行时可以获取的额外信息包括全局变量、类中的静态成员、ThreadLocal 中的值、配置属性等。ApplicationContext 是运行 Spring Framework 应用时的上下文可以借助 ApplicationContext 拿到 IOC 容器中的其他 Bean无论我们在代码中是否获取和使用这些 Bean 都是客观存在的。

相关新闻

原生多模态模型LongCat-Next:统一表示学习与跨模态推理实践

原生多模态模型LongCat-Next:统一表示学习与跨模态推理实践

1. 项目概述:当AI真正“听懂”也“看懂”最近,美团技术团队发布了一个名为“LongCat-Next”的原生多模态模型,在圈内引起了不小的讨论。这个名字听起来有点意思,“LongCat”直译是“长猫”,可能暗示着模型在处理长序列…

2026/10/14 6:41:07 阅读更多 →
沙箱(Sandbox)概念、作用、解决的问题与适用项目

沙箱(Sandbox)概念、作用、解决的问题与适用项目

1. 概念 沙箱是一个隔离的、受控的执行环境。 在 AI Agent(尤其是 LangChain Deep Agents)场景下,它是一个独立的“小电脑”或容器: Agent 可以在里面自由读写文件、运行 Shell 命令、安装依赖、执行代码。但它和你的真实电脑&…

2026/10/8 21:29:21 阅读更多 →
阴阳师自动化脚本终极指南:3步实现游戏全托管,每天节省3小时

阴阳师自动化脚本终极指南:3步实现游戏全托管,每天节省3小时

阴阳师自动化脚本终极指南:3步实现游戏全托管,每天节省3小时 【免费下载链接】OnmyojiAutoScript Onmyoji Auto Script | 阴阳师脚本 项目地址: https://gitcode.com/gh_mirrors/on/OnmyojiAutoScript 阴阳师自动化脚本(Onmyoji Auto …

2026/10/7 3:55:11 阅读更多 →

最新新闻

Java基础探秘:JSON解析与反射机制如何协同工作

Java基础探秘:JSON解析与反射机制如何协同工作

最近在写一个接口的时候,我盯着IDE里那几十行setter调用,脑子里突然冒出一个问题:前端传过来一段JSON字符串,我一行代码就把它变成了业务对象,中间到底是谁在帮我完成键名和字段的匹配?顺着这个疑问查下去&…

2026/10/14 6:41:29 阅读更多 →
QGIS 加载天地图出现灰色影像:层级参数 l 与 z 的坑,附四种返回码对照

QGIS 加载天地图出现灰色影像:层级参数 l 与 z 的坑,附四种返回码对照

场景QGIS 里挂天地图底图,图层加成功了,瓦片也在刷,画面却是一片灰,每个格子上写着"此级别下,该区域无影像"。打开浏览器 F12 一看,状态码 200,图片也确实回来了。这时候大多数人会往…

2026/10/14 6:41:29 阅读更多 →
Agent通信协议选型指南:JSON-RPC、MCP、A2A与ACP的分层实践

Agent通信协议选型指南:JSON-RPC、MCP、A2A与ACP的分层实践

1. 为什么 Agent 通信协议突然“百花齐放”过去一年里,只要你在做 AI Agent 相关的开发,几乎绕不开一个困惑:同样是让两个智能体互相说话,怎么一会儿是 JSON-RPC,一会儿是 MCP,转头又冒出 A2A、ACP&#xf…

2026/10/14 6:41:29 阅读更多 →
Chat2DB 实战:AI 生成 SQL 的数据库管理工具与避坑指南

Chat2DB 实战:AI 生成 SQL 的数据库管理工具与避坑指南

简介:Chat2DB项目代码包是一份集成人工智能能力的开源数据库管理工具示例,面向需要降低数据库操作门槛的开发者、数据分析师以及对自然语言生成SQL感兴趣的技术人员。整个资源共包含3个文件,涵盖inscode入口文件、html介绍文档以及gitignore配…

2026/10/14 6:41:29 阅读更多 →
PS5串流实战:AnyPS5配置与网络调优全攻略

PS5串流实战:AnyPS5配置与网络调优全攻略

把一台PS5玩出三台机器的效果,是不少玩家都在琢磨的事。AnyPS5这个项目,说白了就是干这件事:让PS5不再被客厅电视绑住,而是把画面和操作实时串流到你手边的任何一块屏幕上——笔记本、平板、手机、甚至办公电脑。我在这个方向上前…

2026/10/14 6:41:29 阅读更多 →
C#调用WebService获取PDF转图片:选型与踩坑实战

C#调用WebService获取PDF转图片:选型与踩坑实战

做C#开发这几年,遇到“调用WebService获取PDF文件再转换为图片”这种需求不算少。可能是一个审批系统需要预览合同,也可能是一个报表平台需要把服务端生成的文件转成缩略图展示。总之核心工作就两件事:把远程文件拿下来,再在本地转…

2026/10/14 6:40:29 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →