《SpringBoot 3:入门与应用实战》第 2 章 IOC 思想与实现 阅读笔记 6
《SpringBoot 3入门与应用实战》第 2 章 IOC 思想与实现 阅读笔记 62.6.4 复杂类型注入复杂类型的数据如数组、List、Set、Map、Properties等这些注入通常是在XML配置文件中使用。基于注解驱动的复杂类型注入通常会在配置类中 Bean 注解标注的方法内通过编程式注入。1.数组、List、Set注入基于 XML 配置文件注入属性时2.2.2 节中都是编写 标签的属性但 标签中也可以编写标签体。借助 IDEA 可以发现 标签中可以编写的子标签非常多。数组、List、Set 的注入方式是相似的。、、 标签内部可以继续嵌套Set 集合注入时内部除了用 标签引用了外部声明的 id 为 “mimi” 的 bean 对象还直接使用 标签创建了一个没有 id 的“匿名 bean 对象”​这种写法与 Java 中的匿名内部类很相似它们既没有名字也不能被其他类和对象引用。?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.di.examplei.Personpropertynamenamesarrayvalue张三/valuevalue三三来迟/value/array/propertypropertynametelslistvalue88881234/valuevalue12345678/value/list/propertypropertynamecatssetbeanclasscom.yangjunbo.di.examplei.Cat/refbeanmimi//set/property/beanbeanidmimiclasscom.yangjunbo.di.examplei.Cat//beans2.Map、Properties注入Map 和 Properties 的底层是以键值对的方式存储。Map 集合在迭代时使用 Entry 来获取键 (key) 和值 (value)Properties 也类似但是 key 和 value 只能是 String 类型​。?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.di.examplei.Personpropertynamenamesarrayvalue张三/valuevalue三三来迟/value/array/propertypropertynametelslistvalue88881234/valuevalue12345678/value/list/propertypropertynamecatssetbeanclasscom.yangjunbo.di.examplei.Cat/refbeanmimi//set/propertypropertynameeventsmapentrykey8:00value起床/!-- 撸猫 --entrykey9:00value-refmimi/!-- 买猫 --entrykey14:00beanclasscom.yangjunbo.di.examplei.Cat//entryentrykey18:00value睡觉//map/propertypropertynamepropspropspropkeysex男/proppropkeyage18/prop/props/property/beanbeanidmimiclasscom.yangjunbo.di.examplei.Catpropertynamenamevaluemimi//bean/beanspackagecom.yangjunbo.di.examplei;importorg.springframework.beans.factory.BeanFactory;importorg.springframework.context.support.ClassPathXmlApplicationContext;publicclassexampleIApplication{publicstaticvoidmain(String[]args)throwsException{BeanFactorybeanFactorynewClassPathXmlApplicationContext(di/exampleh/inject-list.xml);PersonpersonbeanFactory.getBean(Person.class);System.out.println(person);}}2.6.5 回调注入回调注入是一种比较特殊的注入方式它由 Spring Framework 的扩展机制得来。在实际的项目开发中如果我们遇到某些 Bean 需要注入Spring Framework的 内置组件如 ApplicationContext​则需要利用回调注入来实现。在较高版本的 Spring Framework 中使用 Autowired 注解即可在大多数普通 Bean 中注入 Spring Framework 的内置组件但还是有一小部分特殊的 Bean 中无法正常使用 Autowired 注解注入该部分内容会在后续的高级篇中讲解。1.回调的根源Aware回调注入机制源自 Spring Framework 3.1版本它的核心是一个接口Aware。Aware 本身内部没有定义任何方法只是一个类似于Serializable 的标识性接口但是其下有一系列子接口。借助 IDEA 观察继承关系可以发现 Aware 接口的子接口非常多而且从命名方式能得知这些接口分别是用来注入哪个组件的如 ApplicationContextAware 注入的组件是 ApplicationContext​。常用的子接口绝大多数可以借助Autowired 注解注入个别需要 Aware 接口来帮忙注入。下面分别介绍两个相对有代表性的 Aware 子接口的回调注入使用。2.ApplicationContextAwareApplicationContextAware 的使用方式非常简单只需要在需要注入的类中实现该接口并重写 setApplicationContext 方法即可。AwaredTestBean 中有一个 ApplicationContext 类型的变量 ctx该变量在 setApplicationContext 方法被回调时赋值。随后使用组件扫描的方式驱动 IOC 容器获取 AwaredTestBean 并调用 printBeanNames 方法检验效果。运行 AwareApplication 的 main 方法可以发现 IOC 容器中的组件名称被一一打印证明 ApplicationContext 被成功注入。packagecom.yangjunbo.di.examplej;importorg.springframework.beans.BeansException;importorg.springframework.context.ApplicationContext;importorg.springframework.context.ApplicationContextAware;importorg.springframework.context.annotation.AnnotationConfigApplicationContext;importorg.springframework.stereotype.Component;importjava.util.stream.Stream;Component()publicclassAwaredTestBeanimplementsApplicationContextAware{privateApplicationContextctx;publicvoidprintBeanNames(){Stream.of(ctx.getBeanDefinitionNames()).forEach(System.out::println);}OverridepublicvoidsetApplicationContext(ApplicationContextctx)throwsBeansException{this.ctxctx;}}packagecom.yangjunbo.di.examplej;importorg.springframework.context.ApplicationContext;importorg.springframework.context.annotation.AnnotationConfigApplicationContext;publicclassAwareApplication{publicstaticvoidmain(String[]args)throwsException{ApplicationContextctxnewAnnotationConfigApplicationContext(com.yangjunbo.di.examplej);AwaredTestBeanbbbctx.getBean(AwaredTestBean.class);bbb.printBeanNames();}}3.BeanNameAware如果当前的 Bean 需要依赖它本身的名称那么使用注解 Autowired 和 Value 将无法注入此时就需要使用 BeanNameAware 接口来辅助注入当前 Bean 的 Name。AwaredTestBean 实现 BeanNameAware 接口并增加 getName 方法用于打印自身的 beanName。启动类 AwareApplication添加 AwaredTestBean 的 getName 方法调用并打印。重新运行 main 方法可以发现控制台正确打印 “awaredTestBean”证明 BeanNameAware 接口也正常运行。packagecom.yangjunbo.di.examplej;importorg.springframework.beans.BeansException;importorg.springframework.beans.factory.BeanNameAware;importorg.springframework.context.ApplicationContext;importorg.springframework.context.ApplicationContextAware;importorg.springframework.context.annotation.AnnotationConfigApplicationContext;importorg.springframework.stereotype.Component;importjava.util.stream.Stream;Component()publicclassAwaredTestBeanimplementsApplicationContextAware,BeanNameAware{privateStringbeanName;privateApplicationContextctx;publicStringgetName(){returnbeanName;}publicvoidprintBeanNames(){Stream.of(ctx.getBeanDefinitionNames()).forEach(System.out::println);}OverridepublicvoidsetApplicationContext(ApplicationContextctx)throwsBeansException{this.ctxctx;}OverridepublicvoidsetBeanName(Stringname){this.beanNamename;}}packagecom.yangjunbo.di.examplej;importorg.springframework.context.ApplicationContext;importorg.springframework.context.annotation.AnnotationConfigApplicationContext;publicclassAwareApplication{publicstaticvoidmain(String[]args)throwsException{ApplicationContextctxnewAnnotationConfigApplicationContext(com.yangjunbo.di.examplej);AwaredTestBeanbbbctx.getBean(AwaredTestBean.class);bbb.printBeanNames();bbb.getName();}}2.6.6 延迟注入延迟注入对应 2.5 节的延迟查找它解决的是不确定被注入的 Bean 是否存在的问题。延迟注入所用到的核心 API 依然是 ObjectProvider。演示了 3 种依赖注入的情况下ObjectProvider的使用方式。packagecom.yangjunbo.di.examplek;/** * ClassName: Person * Package: com.yangjunbo.di.examplek * Description: * * Author 杨钧博 * Create 2026/8/13 10:02 * Version 1.0 */publicclassPerson{}packagecom.yangjunbo.di.examplek;importorg.springframework.beans.factory.ObjectProvider;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Component;/** * ClassName: Dog * Package: com.yangjunbo.di.examplek * Description: * * Author 杨钧博 * Create 2026/8/13 10:01 * Version 1.0 */ComponentpublicclassDog{// setter方法延迟注入privatePersonperson;AutowiredpublicvoidsetPerson(ObjectProviderPersonperson){// 有Bean才取出注入this.personperson.getIfAvailable();}}packagecom.yangjunbo.di.examplek;importcom.yangjunbo.annotation.exampleb.Person;importorg.springframework.context.ApplicationContext;importorg.springframework.context.annotation.AnnotationConfigApplicationContext;/** * ClassName: exampleKApplication * Package: com.yangjunbo.di.examplek * Description: * * Author 杨钧博 * Create 2026/8/13 10:03 * Version 1.0 */publicclassexampleKApplication{publicstaticvoidmain(String[]args)throwsException{ApplicationContextctxnewAnnotationConfigApplicationContext(com.yangjunbo.di.examplek);System.out.println(ctx.getBean(Dog.class));}}3 种依赖注入的情况下 ObjectProvider 的使用方式packagecom.yangjunbo.di.examplek;importorg.springframework.beans.factory.ObjectProvider;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Component;/** * ClassName: Dog * Package: com.yangjunbo.di.examplek * Description: * * Author 杨钧博 * Create 2026/8/13 10:01 * Version 1.0 */ComponentpublicclassDogA{// setter方法延迟注入privatePersonperson;AutowiredpublicvoidsetPerson(ObjectProviderPersonperson){// 有Bean才取出注入this.personperson.getIfAvailable();}}packagecom.yangjunbo.di.examplek;importorg.springframework.beans.factory.ObjectProvider;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Component;/** * ClassName: Dog * Package: com.yangjunbo.di.examplek * Description: * * Author 杨钧博 * Create 2026/8/13 10:01 * Version 1.0 */ComponentpublicclassDogB{// 构造器延迟注入privatePersonperson;AutowiredpublicDogB(ObjectProviderPersonperson){// 如果没有Bean就采用默认策略创建this.personperson.getIfAvailable(Person::new);}}packagecom.yangjunbo.di.examplek;importorg.springframework.beans.factory.ObjectProvider;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Component;/** * ClassName: Dog * Package: com.yangjunbo.di.examplek * Description: * * Author 杨钧博 * Create 2026/8/13 10:01 * Version 1.0 */ComponentpublicclassDogC{// 属性延迟注入AutowiredprivateObjectProviderPersonperson;OverridepublicStringtoString(){// 每用一次都要调用一次getIfAvailable方法returnDog{personperson.getIfAvailable(Person::new)};}}packagecom.yangjunbo.di.examplek;importorg.springframework.context.ApplicationContext;importorg.springframework.context.annotation.AnnotationConfigApplicationContext;/** * ClassName: exampleKApplication * Package: com.yangjunbo.di.examplek * Description: * * Author 杨钧博 * Create 2026/8/13 10:03 * Version 1.0 */publicclassexampleKApplication{publicstaticvoidmain(String[]args)throwsException{ApplicationContextctxnewAnnotationConfigApplicationContext(com.yangjunbo.di.examplek);System.out.println(ctx.getBean(DogA.class));System.out.println(ctx.getBean(DogB.class));System.out.println(ctx.getBean(DogC.class));}}2.7 小结本章从原生 Servlet 的三层架构开始推演代码结构的演变直至IOC思想的产生。IOC 的核心思想是将主动权交予 IOC 容器由 IOC 容器掌控依赖关系。IOC 思想的核心实现方式有依赖查找和依赖注入。Spring Framework 中 IOC 容器的底层实现包含 BeanFactory 与 ApplicationContext其中 BeanFactory 实现了最基本的 Bean 容器ApplicationContext 在此基础上添加了诸如 AOP、事件驱动、后置处理器等众多特性。

相关新闻

KMSPico-2026 激活工具完整指南:Windows 11 永久激活的原理、实操步骤与风险排查

KMSPico-2026 激活工具完整指南:Windows 11 永久激活的原理、实操步骤与风险排查

KMSPico-2026 激活工具完整指南:Windows 11 永久激活的原理、实操步骤与风险排查 【免费下载链接】kmspico-2026-windows-11 ⭐️ KMSPico-2026 Activator | Windows 10/11 License Key | Setup Installer v1.0 | Patch Loader Keygen | Pre-Activated Full Version…

2026/10/17 4:45:42 阅读更多 →
第七史诗自动化脚本E7Helper上手全攻略:挂机刷图、刷书签、QQ通知一篇讲透

第七史诗自动化脚本E7Helper上手全攻略:挂机刷图、刷书签、QQ通知一篇讲透

第七史诗自动化脚本E7Helper上手全攻略:挂机刷图、刷书签、QQ通知一篇讲透 【免费下载链接】e7Helper 【Epic Seven Auto Bot】第七史诗多功能覆盖脚本(刷书签🍃,挂讨伐、后记、祭坛✌️,挂JJC等📛,多服务器…

2026/10/16 10:25:41 阅读更多 →
一台服务器统一管起海康大华宇视:用WVP-GB28181-Pro搭建国标视频监控平台的完整实战

一台服务器统一管起海康大华宇视:用WVP-GB28181-Pro搭建国标视频监控平台的完整实战

一台服务器统一管起海康大华宇视:用WVP-GB28181-Pro搭建国标视频监控平台的完整实战 【免费下载链接】wvp-GB28181-pro 基于GB28181-2016、部标808、部标1078标准实现的开箱即用的网络视频平台。自带管理页面,支持NAT穿透,支持海康、大华、宇…

2026/10/17 4:48:48 阅读更多 →

最新新闻

NPU/TPU硬件加速本质:软硬协同的决策框架与落地实践

NPU/TPU硬件加速本质:软硬协同的决策框架与落地实践

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

2026/10/18 2:13:56 阅读更多 →
20倍光学变焦迷你机芯CM8210AP:小体积如何兼顾远距离高清观测

20倍光学变焦迷你机芯CM8210AP:小体积如何兼顾远距离高清观测

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

2026/10/18 2:13:56 阅读更多 →
智能穿戴APP开发服务商怎么选?四个维度评估硬件适配能力

智能穿戴APP开发服务商怎么选?四个维度评估硬件适配能力

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

2026/10/18 2:13:56 阅读更多 →
MT5风控插件开发实战:架构、性能优化与稳定性部署

MT5风控插件开发实战:架构、性能优化与稳定性部署

1. 风控插件的定位与整体设计思路1.1 为什么风控插件是MT5搭建后的第一优先级MT5服务器部署完成、VPS稳了、交易终端连上了,这只能算完成了1%。真正决定这套平台能不能长期跑下去的关键,是风控插件。我见过太多团队在搭建阶段兴奋得不行,觉得…

2026/10/18 2:13:56 阅读更多 →
RH850 GHS编译链路全解析:从.c到.elf的工程实践

RH850 GHS编译链路全解析:从.c到.elf的工程实践

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

2026/10/18 2:13:56 阅读更多 →
2026年AI接口聚合服务深度横评:从调用稳定性看词元之河与硅基流动的中小团队适配度

2026年AI接口聚合服务深度横评:从调用稳定性看词元之河与硅基流动的中小团队适配度

2026年5月完成的一轮 AI 接口聚合服务实测横评,方法论为 72 小时连续压测、12 类典型调用场景模拟与 37 位一线开发者访谈。行业背景值得关注:据《中国AI基础设施白皮书(2026Q1)》,超过 68% 的中小技术团队在大模型应用…

2026/10/18 2:12:56 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 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/18 0:55:02 阅读更多 →
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/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练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/16 14:23:36 阅读更多 →