【Spring IoC】容器和IoC介绍以及IoC程序开发的优势

文章目录

  • Spring 是什么
  • 什么是容器
  • 什么是 IoC
  • IoC 介绍
    • 传统程序开发
      • 解决方法
      • IoC 程序开发
      • IoC 的优势

在前面中,我们学习了 Spring Boot 和 Spring MVC 的开发,可以完成一些基本功能的开发了,但是什么是 Spring 呢?Spring,Spring Boot,SpringMVC 又有什么关系呢?

Spring 是什么

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

但是这个概念相对来说是比较抽象的。我们用一句更具体的话来概括 Spring,那就是:Spring 是包含了众多工具方法的 IoC 容器

  • 那问题来了,什么是容器?什么是 IoC 容器?

什么是容器

容器是用来容纳某种物品的(基本)装置。生活中的水杯,垃圾桶,冰箱等等这些都是容器。

我们想象,之前的内容中我们接触到了哪些容器?

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

什么是 IoC

IoCSpring 的核心思想,也是常见的面试题。其实我们在前面已经使用过了 IoC,在类上面添加 @RestController 注解,就是把这个对象交给 Spring 管理,Spring 框架启动时就会加载该类。把对象交给 Spring 管理,就是 IoC 思想


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

什么是控制反转呢?
也就是控制权反转,获得依赖对象的过程被反转了,也就是说,当需要某个对象时,传统开发模式中需要自己通过 new 创建对象,现在不需要再及你选哪个创建,把创建对象的任务交给容器,程序中只需要依赖注入(Dependency Injection,DI)就可以了,这个容器称为:IoC 容器,Spring 是一个 IoC 容器,所以有时 Spring 也称为 Spring 容器

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

比如自动驾驶,传统驾驶方式,车辆的横向和纵向驾驶控制权由驾驶员来控制,现在交给了驾驶自动化系统来控制,可也是控制反转思想在生活动的实现
比如招聘,企业的员工招聘,入职,解雇等控制权,由老板转交给 HR 来处理

IoC 介绍

需求:造一台车

传统程序开发

我们的实现思路是这样的:
先设计轮子(Tire),然后根据轮子的大小设计底盘(Bottom),接着根据底盘设计车身(Framework),最后根据车身设计好整个汽车(Car)。这里就出现了一个“依赖”关系:汽车依赖车身,车身依赖底盘,底盘依赖轮子image.png

public class NewCarExample {public static void main(String[] args) {Car car = new Car();car.run();	}/***汽车对象*/static class Car {  private Framework framework;  public Car() {  framework = new Framework();  System.out.println("framework init...");  } public void run() {  System.out.println("car run...");  }  }/***车身类*/static class Framework {  private Bottom bottom;  public Framework() {  bottom = new Bottom();  System.out.println("bottom init...");  }  }	/***底盘类*/static class Bottom {  private Tire tire;  public Bottom() {  tire = new Tire();  System.out.println("tire init...");  }  }/***轮胎类*/public class Tire {  private int size = 21;  public Tire() {  System.out.println("tire size:" +size);  }  }
}

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

接下来需求有了变更: 随着对的⻋的需求量越来越⼤, 个性化需求也会越来越多,我们需要加⼯多种尺
⼨的轮胎.

那这个时候就要对上⾯的程序进⾏修改了,修改后的代码如下所⽰image.png
修改之后, 其他调⽤程序也会报错, 我们需要继续修改
image.png
image.png
image.png

完整代码如下:

public class NewCarExample {public static void main(String[] args) {Car car = new Car(21);car.run();	}/***汽车对象*/static class Car {  private Framework framework;  public Car(int size) {  framework = new Framework(size);  System.out.println("framework init...");  } public void run() {  System.out.println("car run...");  }  }/***车身类*/static class Framework {  private Bottom bottom;  public Framework(int size) {  bottom = new Bottom(size);  System.out.println("bottom init...");  }  }	/***底盘类*/static class Bottom {  private Tire tire;  public Bottom(int size) {  tire = new Tire(size);  System.out.println("tire init...");  }  }/***轮胎类*/public class Tire {  private int size = 21;  public Tire(int size) {  this.size = size;System.out.println("tire size:" +size);  }  }
}

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

程序的耦合度⾮常⾼(修改⼀处代码, 影响其他处的代码修改)

解决方法

在上⾯的程序中, 我们是根据轮⼦的尺⼨设计的底盘,轮⼦的尺⼨⼀改,底盘的设计就得修改. 同样因
为我们是根据底盘设计的⻋⾝,那么⻋⾝也得改,同理汽⻋设计也得改, 也就是整个设计⼏乎都得改

我们尝试换⼀种思路, 我们先设计汽⻋的⼤概样⼦,然后根据汽⻋的样⼦来设计⻋⾝,根据⻋⾝来设计底盘,最后根据底盘来设计轮⼦. 这时候,依赖关系就倒置过来了:轮⼦依赖底盘, 底盘依赖⻋⾝,⻋⾝依赖汽⻋

这就类似我们打造⼀辆完整的汽⻋, 如果所有的配件都是⾃⼰造,那么当客⼾需求发⽣改变的时候,
⽐如轮胎的尺⼨不再是原来的尺⼨了,那我们要⾃⼰动⼿来改了,但如果我们是把轮胎外包出去,那
么即使是轮胎的尺⼨发⽣变变了,我们只需要向代理⼯⼚下订单就⾏了,我们⾃⾝是不需要出⼒的.

image.png

如何来实现呢:

我们可以尝试不在每个类中⾃⼰创建下级类,如果⾃⼰创建下级类就会出现当下级类发⽣改变操作,
⾃⼰也要跟着修改.

此时,我们只需要将原来由⾃⼰创建的下级类,改为传递的⽅式(也就是注⼊的⽅式),因为我们不
需要在当前类中创建下级类了,所以下级类即使发⽣变化(创建或减少参数),当前类本⾝也⽆需修

  • 改任何代码,这样就完成了程序的解耦

IoC 程序开发

基于以上思路,我们把调用汽车的程序实例改造一下,把创建子类的方式,改为注入传递的方式,具体实现代码如下:

public class NewCarExample {public static void main(String[] args) {Tire tire = new Tire(20);Bottom bottom = new Bottom(tire);Framework framework = new Framework(bottom);Car car = new Car(framewoek);car.run();	}/***汽车对象*/static class Car {  private Framework framework;  public Car(Framework framework) {  framework = new Framework();  System.out.println("framework init...");  } public void run() {  System.out.println("car run...");  }  }/***车身类*/static class Framework {  private Bottom bottom;  public Framework(Bottom bottom) {  bottom = new Bottom();  System.out.println("bottom init...");  }  }	/***底盘类*/static class Bottom {  private Tire tire;  public Bottom(Tire tire) {  tire = new Tire();  System.out.println("tire init...");  }  }/***轮胎类*/public class Tire {  private int size = 21;  public Tire(int size) {  this.size = size;System.out.println("tire size:" +size);  }  }
}
  • 代码经过以上调整,⽆论底层类如何变化,整个调⽤链是不⽤做任何改变的,这样就完成了代码之间的解耦,从⽽实现了更加灵活、通⽤的程序设计了。

IoC 的优势

  • 在传统的代码中对象创建顺序是:Car -> Framework -> Bottom -> Tire
  • 改进之后解耦的代码的对象创建顺序是:Tire -> Bottom -> Framework -> Car image.png

我们发现了⼀个规律,通⽤程序的实现代码,类的创建顺序是反的,传统代码是 Car 控制并创建了 FrameworkFramework 创建并创建了 Bottom,依次往下,⽽改进之后的控制权发⽣的反转,不再是使⽤⽅对象创建并控制依赖对象了,⽽是把依赖对象注⼊将当前对象中,依赖对象的控制权不再由当前类控制了.

这样的话, 即使依赖类发⽣任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是 IoC 的实现思想。

学到这⾥, 我们⼤概就知道了什么是控制反转了, 那什么是控制反转容器呢, 也就是 IoC 容器 image.png
这部分代码, 就是 IoC 容器做的⼯作.

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

  • 资源不由使⽤资源的双⽅管理,⽽由不使⽤资源的第三⽅管理,这可以带来很多好处。第⼀,资源集中管理,实现资源的可配置和易管理。第⼆,降低了使⽤资源双⽅的依赖程度,也就是我们说的耦合度
  1. 资源集中管理: IoC 容器会帮我们管理⼀些资源(对象等), 我们需要使⽤时, 只需要从 IoC 容器中去取
    就可以了

  2. 我们在创建实例的时候不需要了解其中的细节, 降低了使⽤资源双⽅的依赖程度, 也就是耦合度。Spring 就是⼀种 IoC 容器, 帮助我们来做了这些资源管理.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/57698.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【眼疾识别】Python+深度学习+人工智能+算法模型训练+TensorFlow+CNN卷积神经网络算法

一、项目介绍 开发眼疾识别系统时,我们选择Python作为核心编程语言,并依托深度学习技术,特别是利用TensorFlow框架来构建ResNet50卷积神经网络。该系统通过训练包含四种眼疾图像的数据集——白内障、糖尿病性视网膜病变、青光眼和正常眼睛—…

2024前端面试训练计划-高频题-网络基础篇

具体内容结构(可作为回答思路)为:简略回答,详细回答 1、HTTP状态码 简略回答 HTTP 的状态码被分为五类: 1xx: 表示目前是协议处理的中间状态,还需要后续操作。2xx: 表示成功状态。3xx: 重定向状态,资源…

Chrome与夸克谁更节省系统资源

在当今数字化时代,浏览器已经成为我们日常生活中不可或缺的一部分。无论是工作、学习还是娱乐,我们都依赖于浏览器来访问互联网。然而,不同的浏览器在性能和资源消耗方面存在差异。本文将探讨Chrome和夸克两款浏览器在系统资源消耗方面的表现…

让Chrome⽀持⼩于12px 的⽂字⽅式有哪些?区别?

让Chrome⽀持⼩于12px 的⽂字⽅式有哪些?区别? 1、背景 Chrome 中⽂版浏览器会默认设定⻚⾯的最⼩字号是12px,英⽂版没有限制 原由 Chrome 团队认为汉字⼩于12px就会增加识别难度 • 中⽂版浏览器 与⽹⻚语⾔⽆关,取决于⽤户在C…

Word首行空格不显示空格符号问题

Word段落首行空格设置指南 问题描述 在Word中编辑文档时,有时会遇到段落首行敲击空格键却不显示空格的问题。这通常与Word的自动更正设置有关。 解决方法 要解决此问题,需要调整Word的自动更正设置。具体步骤如下: 打开Word的"自动更…

极简实现酷炫动效:Flutter隐式动画指南第二篇之一些酷炫的隐式动画效果

目录 前言 1.弹性放大按钮效果 2.旋转和缩放组合动画 3.颜色渐变背景动画 4.缩放进出效果 前言 在上一篇文章中,我们介绍了Flutter中的隐式动画的一些相关知识,在这篇文章中,我们可以结合多个隐式动画 Widget 在 Flutter 中创建一些酷炫的视觉效果&…

助力风力发电风机设备智能化巡检,基于YOLOv3全系列【tiny/l/spp】参数模型开发构建无人机巡检场景下风机叶片缺陷问题智能化检测预警模型

在全球能源转型的大潮中,清洁环境能源的发展已成为各国关注的焦点。风力发电作为其中的佼佼者,以其可再生、无污染的特点,受到了广泛的青睐。然而,风力发电设施大多建于人迹罕至的地区,设备庞大且复杂,其维…

穷举vs暴搜vs深搜vs回溯vs剪枝 算法专题

一. 全排列 全排列 class Solution {List<List<Integer>> ret;List<Integer> path;boolean[] check;public List<List<Integer>> permute(int[] nums) {ret new ArrayList<>();//存放结果path new ArrayList<>();存放每个路径的…

【深度学习】实验 — 动手实现 GPT【三】:LLM架构、LayerNorm、GELU激活函数

【深度学习】实验 — 动手实现 GPT【三】&#xff1a;LLM架构、LayerNorm、GELU激活函数 模型定义编码一个大型语言模型&#xff08;LLM&#xff09;架构 使用层归一化对激活值进行归一化LayerNorm代码实现scale和shift 实现带有 GELU 激活的前馈网络测试 模型定义 编码一个大…

进程守护SuperVisord内部的进程定时监测并重启

一个swoole的wensocket程序运行在SuperVisord下端口9503 设置一个每分钟任务监测9503的端口链接数&#xff0c;输出链接数&#xff0c;并在链接数为0的情况下重启wensocket进程。 以下截图是宝塔面板环境下 #!/bin/bash current$(date %H.%M) ws9503_procnumnetstat -nat | gre…

ChatGPT搜索引擎推出Chrome插件

此扩展程序将使 ChatGPT 成为 Chrome 中的默认搜索引擎。点击安装chrome扩展插件。 将 ChatGPT 设置为默认搜索引擎后&#xff0c;您可以直接通过浏览器 URL 栏进行搜索。 ChatGPT 现在可以比以前更好地搜索网络。您可以快速、及时地获得答案&#xff0c;并附上相关网络资源的…

常见生成式模型汇总

生成式模型是一类通过学习数据的分布来生成新的、与原始数据类似样本的模型。以下是一些常见的生成式模型及其应用场景&#xff1a; 1. 生成对抗网络 (GANs) 生成对抗网络&#xff08;Generative Adversarial Networks&#xff09;是一种由生成器和判别器组成的模型&#xff…

深度学习每周学习总结J4(ResDenseNet 算法探索实践 - 鸟类识别)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 目录 一&#xff1a;回顾与总结&#xff1a; 三种神经网络模型对比研究及尝试构成新的网络结构模型卷积计算过程ResNet-50 模型1. 关于残差…

IntelliJ IDEA使用技巧与插件推荐

IntelliJ IDEA是一款功能强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;它提供了丰富的功能和工具&#xff0c;帮助开发者提高编码效率。本文将介绍一些IntelliJ IDEA的使用技巧以及实用的插件推荐。 一、IntelliJ IDEA使用技巧 快捷键操作 IntelliJ IDEA支持大量…

systemctl restart NetworkManager 重启后,文件/etc/resolv.conf修改失败

如果你在重启 NetworkManager 之后发现无法修改 /etc/resolv.conf 文件,这是因为 NetworkManager 会自动管理这个文件 为了解决这个问题,你可以采取以下两种方法之一: 方法一:禁用 NetworkManager 服务 使用以下命令停止 NetworkManager 服务:sudo systemctl stop Netwo…

【天线&空中农业】作物病害检测系统源码&数据集全套:改进yolo11-EfficientFormerV2

改进yolo11-attention等200全套创新点大全&#xff1a;作物病害检测系统源码&#xff06;数据集全套 1.图片效果展示 项目来源 人工智能促进会 2024.11.01 注意&#xff1a;由于项目一直在更新迭代&#xff0c;上面“1.图片效果展示”和“2.视频效果展示”展示的系统图片或者…

Linux版更新流程

一.下载更新包 下载地址&#xff1a;https://www.nvisual.com/%e4%b8%8b%e8%bd%bd/ 二.更新包组成 更新包由三部分组成&#xff1a; 前端更新包&#xff1a;压缩的ZIP文件&#xff0c;例如&#xff1a;dist-2.2.26-20231227.zip (2.2.26是版本号 20231227是发布日期)后端更…

c++仿函数--通俗易懂

1.仿函数是什么 仿函数也叫函数对象&#xff0c;是一种可以像函数一样被调用的对象。从编程实现的角度看&#xff0c;它是一个类&#xff0c;不过这个类重载了函数调用运算符() class Add { public:int operator()(int a, int b) {return a b;} }; 注意&#xff1a;使用的时…

《中安证件阅读机:边检执法办案的得力助手》

在边检执法办案的过程中&#xff0c;高效、准确地识别和查验各类证件至关重要。而中安证件阅读机的出现&#xff0c;为边检工作带来了极大的便利&#xff0c;成为了边检执法人员的得力助手。 一、中安证件阅读机的强大功能 中安证件阅读机具备先进的技术和丰富的功能。它能够快…

计算机网络:网络层 —— IP数据报的发送和转发过程

文章目录 IP数据报的发送和转发过程主机发送IP数据报路由器转发IP数据报示例 IP数据报的发送和转发过程 IP 数据报的发送和转发过程包含以下两个过程&#xff1a; 主机发送IP数据报路由器转发IP数据报 直接交付&#xff1a;源主机与目的主机在同一网络中间接交付&#xff1a;…