【Spring IoC DI】深入解析 IoC & DI :Spring框架的核心设计思想和 IoC 与 DI 的思想和解耦优势

news/2025/3/25 22:13:12/

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


IoCDI_strongfontfontfont_19"> Spring IoC&DI


本节目标

  1. 了解Spring, Spring MVC, Spring Boot 之间的联系及区别
  2. 掌握IoC&DI的概念以及写法

IoC__DI_strongfontfontfontfont_color__redfont_facefont_size6strongstrongfontfontfont_30">IoC & DI 入门


在前面的章节中,我们学习了Spring Boot和Spring MVC的开发,可以完成一些基本功能的开发了,但是什么是Spring呢?Spring, Spring Boot 和Spring MVC又有什么关系呢?咱们还是带着问题去学习。

我们先看什么是Spring


Spring 是什么?


通过前面的学习,我们知道了Spring是一个开源框架,它让我们的开发更加简单。它支持广泛的应用场景,有着活跃而庞大的社区,这也是Spring能够长久不衰的原因。

但是这个概念相对来说,还是比较抽象。

我们用一句更具体的话来概括Spring,那就是:Spring 是包含了众多工具方法的 IoC 容器

那问题来了,什么是容器?什么是 IoC 容器?接下来我们一起来看


什么是容器?


容器是用来容纳某种物品的(基本)装置。——来自:百度百科

生活中的水杯、垃圾桶、冰箱等等这些都是容器。

我们想想,之前课程我们接触的容器有哪些?

  • List / Map -> 数据存储容器
  • Tomcat -> Web 容器

IoC_strongfontfontfont_69">什么是IoC


IoCSpring核心思想,也是常见的面试题,那什么是IoC呢?


其实IoC我们在前面已经使用了,我们在前面讲到:

上面添加 @RestController@Controller 注解,就是把这个对象交给Spring管理

Spring框架启动时就会加载该类

对象交给Spring管理,就是IoC思想。


IoC: Inversion of Control(控制反转),也就是说 Spring 是一个“控制反转”的容器。

  • 什么是控制反转呢?
    • 也就是控制权反转

  • 什么的控制权发生了反转?
    • 获得依赖对象的过程被反转了;
    • 也就是说,当需要某个对象时,传统开发模式中需要自己通过 new 创建对象,现在不需要再进行创建;
    • 把创建对象的任务交给容器,程序中只需要依赖注入(Dependency Injection,DI)就可以了;

  • 这个容器称为:IoC容器
    • Spring是一个IoC容器,所以有时Spring也称为Spring 容器

控制反转是一种思想,在生活中也是处处体现。

  • 比如自动驾驶:
    • 传统驾驶方式,车辆的横向和纵向驾驶控制权由驾驶员来控制;
    • 现在交给了驾驶自动化系统来控制,这也是控制反转思想在生活中的实现。
  • 比如招聘:
    • 企业的员工招聘、入职、解雇等控制权,由老板转交给HR(人力资源)来处理

IoC_strongfontfontfontfont_color__greefont_facefont_size6strongstrongfontfontfont_112"> IoC 介绍


接下来我们通过案例来了解一下什么是 IoC

需求:造一辆车

在这里插入图片描述


在这里插入图片描述


传统程序开发


我们的实现思路是这样的:

  • 先设计轮子(Tire);
  • 然后根据轮子的大小设计底盘(Bottom);
  • 接着根据底盘设计车身(Framework);
  • 最后根据车身设计好整个汽车(Car)。
  • 这里就出现了一个“依赖”关系:汽车依赖车身,车身依赖底盘,底盘依赖轮子。

在这里插入图片描述


我们按照上图的顺序,依次构造类:

在这里插入图片描述


new Car(),就是调用 Car 的构造方法:

在这里插入图片描述


因为我们构造一个 car 对象,就依赖一个 framework 对象;

同理,构造一个 framework 对象,就依赖于一个 buttom 对象;

构造一个 buttom 对象,就依赖于一个 tire 对象;

在这里插入图片描述


运行 main 方法:

在这里插入图片描述


问题分析


这样的设计看起来没问题,但是可维护性却很低。

接下来需求有了变更:随着对的车的需求量越来越大,个性化需求也会越来越多,我们需要加工多种尺寸的轮胎

那这个时候就要对上面的程序进行修改了,修改后的代码如下所示:

在这里插入图片描述


修改之后,其他调用程序也会报错,我们需要继续修改

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


完整代码如下

在这里插入图片描述


从以上代码可以看出,以上程序的问题是:当最底层代码改动之后,整个调用链上的所有代码都需要修改

程序的耦合度非常高(修改一处代码,影响其他处的代码修改)


解决方案


在上面的程序中:

  • 我们是根据轮子的尺寸设计的底盘;

  • 轮子的尺寸一改,底盘的设计就得修改;

  • 同理,因为我们是根据底盘设计的车身,那么车身也得改;

  • 同理,车身一修改,汽车设计也得改,也就是整个设计几乎都得改。


我们尝试换一种思路:

  • 我们先设计汽车的大概样子;

  • 然后根据汽车的样子来设计车身;

  • 根据车身来设计底盘;

  • 最后根据底盘来设计轮子;


这时候,依赖关系就倒置过来了:轮子依赖底盘,底盘依赖车身,车身依赖汽车。


这就类似我们打造一辆完整的汽车:

  • 如果所有的配件都是自己造:
    • 那么当客户需求发生改变的时候,比如轮胎的尺寸不再是原来的尺寸了,那我们要自己动手来改了;

  • 但如果我们是把轮胎外包出去:
    • 那么即使是轮胎的尺寸发生变化,我们只需要向代理工厂下订单就行了,我们自身是不需要出力的。

在这里插入图片描述


如何来实现呢:

  • 我们可以尝试不在每个类中自己创建下级类:

    • 如果自己创建下级类就会出现当下级类发生改变操作,自己也要跟着修改。
  • 此时,我们只需要将原来由自己创建的下级类,改为传递的方式(也就是注入的方式):

    • 我们不需要在当前类中创建下级类了:
    • 所以下级类即使发生变化(创建或减少参数),当前类本身也无需修改任何代码;
    • 这样就完成了程序的解耦

IoC_strongfontfontfontfont_color__bluefont_facefont_size6strong_____strongfontfontfont_283"> IoC 程序开发


基于以上思路,我们把调用汽车的程序示例改造一下,把创建子类的方式,改为注入传递的方式。

具体实现代码如下:

在这里插入图片描述


修改前:

在这里插入图片描述


对比一下 v1 和 v2 的设计模式, v2 中的构造方法不再 new 下一层结构,而是通过传参的方式,拿到下一层结构:

在这里插入图片描述


修改后:

在这里插入图片描述


我们在来看 main 方法的调整:

  • 此时就可以把底层类看作是外包公司,main 就相当于我们的售车店;

  • 我们不再像 v1 一样,只要一修改某一个环节,就要亲历亲为的修改所有底层类

    • 客户需要什么尺寸,都可以在售车店 main 中直接提出来;
    • 售车店拿到订单后,直接交给外包公司即可;
    • 外包公司根据 main 提交的订单针对性生产即可;

在这里插入图片描述


重新运行程序:

在这里插入图片描述


代码经过以上调整,无论底层类如何变化,整个调用链是不用做任何改变的:

在这里插入图片描述

上图中,我们对车身有了新的颜色要求,此时修改车身颜色,整个供应链只有车身报错;


在这里插入图片描述

这样就完成了代码之间的解耦,从而实现了更加灵活、通用的程序设计了。


IoC_strongfontfontfontfont_color__bluefont_facefont_size6strong_____strongfontfontfont_353"> IoC 优势


在传统的代码中对象创建顺序是:Car -> Framework -> Bottom -> Tire

改进之后解耦的代码的对象创建顺序是:Tire -> Bottom -> Framework -> Car

在这里插入图片描述


我们发现了一个规律,通用程序的实现代码,类的创建顺序是反的:

  • 传统代码是 Car 控制并创建了 Framework,Framework 创建并创建了 Bottom,依次往下;

而改进之后的控制权发生的反转:

  • 不再是使用方对象创建并控制依赖对象了;

  • 而是把依赖对象注入当前对象中,依赖对象的控制权不再由当前类控制了。

  • 这样的话,即使依赖类发生任何改变,当前类都是不受影响的;

这就是典型的控制反转,也就是 IoC 的实现思想。


学到这里,我们大概就知道了什么是控制反转了,那什么是控制反转容器呢,也就是IoC容器

在这里插入图片描述

这部分代码,就是IoC容器做的工作。


从上面也可以看出来,IoC容器具备以下优点:

资源不由使用资源的双方管理,而由不使用资源的第三方管理,这可以带来很多好处:

  • 第一,资源集中管理,实现资源的可配置和易管理。

  • 第二,降低了使用资源双方的依赖程度,也就是我们说的耦合度

  1. 资源集中管理:IoC容器会帮我们管理一些资源(对象等),我们需要使用时,只需要从IoC容器中去取就可以了。
  2. 我们在创建实例的时候不需要了解其中的细节,降低了使用资源双方的依赖程度,也就是耦合度

Spring 就是一种 IoC容器,帮助我们来做这些资源管理。


DI__strongfontfontfontfont_color__greefont_facefont_size6strongstrongfontfontfont_407"> DI 介绍


上面学习了IoC,什么是DI呢?

DI:Dependency Injection(依赖注入

容器在运行期间,动态的为应用程序提供运行时所依赖的资源,称之为依赖注入

  • 程序运行时需要某个资源,此时容器就为其提供这个资源

  • 从这点来看,依赖注入(DI控制反转(IoC)是从不同的角度的描述的同一件事情

    • 依赖注入是从应用程序的角度来描述;
    • 就是指通过引入 IoC 容器,利用依赖关系注入的方式,实现对象之间解耦

上述代码中,是通过构造函数的方式,把依赖对象注入到需要使用的对象中的

在这里插入图片描述


IoC 是一种思想,也是“目标”,而思想只是一种指导原则,最终还是要有可行的落地方案,而 DI 就属于具体的实现。所以也可以说,DIIoC的一种实现。

比如说我今天心情比较好,吃一顿好的犒劳犒劳自己,那么“吃一顿好的”是思想和目标(是 IoC),但最后我是吃海底捞还是杨国福?这就是具体的实现,就是 DI


在这里插入图片描述

在这里插入图片描述


http://www.ppmy.cn/news/1582556.html

相关文章

Rust基础语法

文章目录 Rust输出到命令行关于变量常量vs不可变变量 数据类型整数浮点数bool字符类型复合类型 注释 Rust输出到命令行 输出到命令行主要可以使用println!()和print!() 1. 这两个都有!是因为他们并非是函数,而是宏,具体我们以后再介绍,普通函…

Linux探秘坊-------9.进程控制

1.进程终止 1.终止情况 终止情况只有三种: 2.终止方式 从main函数返回 exit(n)的参数n就是退出码!!!!!!!!!!&#xf…

k8s搭建kube-prometheus

后续再补一个k8s集群搭建的博客,从0开始搭建k8s集群。使用kube-prometheus非常方便,主要问题只在于拉取镜像。除了拉取镜像外其他时间5分钟即可。耐心等待拉取镜像。 一.kube-prometheus简介 kube-prometheus 是一个专为 Kubernetes 设计的开源监控解决…

网络华为HCIA+HCIP 广域网技术

目录 PPP协议 PPP链路建立流程 PPP链路接口状态机 LCP报文格式 LCP协商过程-正常协商 LCP协商过程-参数不匹配(MRU) LCP协商过程-参数不识别 PPP认证模式 - PAP PPP认证模式 - CHAP NCP协商 - 静态IP地址协商 NCP协商 - 动态IP地址协商 P…

基于改进蛙跳算法的电动汽车有序充电策略研究

摘要:本文针对电动汽车无序充电对电网造成的影响,提出了一种基于改进蛙跳算法的有序充电策略。该策略通过引入动态惯性权重和自适应分组机制,优化了传统蛙跳算法的性能。建立了以超小化电网负荷波动、用户充电成本和电池损耗为目标的有序充电模型&#x…

Web3 环境下用户数据隐私保护的技术方案分析

Web3 环境下用户数据隐私保护的技术方案分析 在这个信息爆炸的时代,Web3 的概念如同一股清流,它不仅代表着技术的革新,更是互联网治理模式的一次重大转变。在 Web3 的世界里,用户数据隐私保护成为了核心议题,它关乎每…

深度学习中的“刹车”:正则化如何防止模型“超速”

深度学习中的“刹车”:正则化如何防止模型“超速” 大家好!今天我们来聊聊深度学习中的一个重要概念——正则化。 什么是过拟合? 想象一下,你正在教一个孩子认字。你给他看很多猫的图片,他都能正确识别。但是&#…

专利信息管理知识产权基于Spring Boot SSM

目录 一、需求分析 1.1系统用户角色与权限 1.2 专利信息管理功能 二、数据分析与报表生成 三、系统性能与安全性 四 用户体验与界面设计 五 扩展性与可维护性 六、法律法规与合规性 七. 技术选型与实现 ‌7.1技术选型‌: ‌7.2实现方式‌: 随…