【Java EE】Spring核心思想(一)——IOC

文章目录

  • 🎍Spring 是什么?
  • 🎄什么是IoC呢?
    • 🌸传统程序开发
    • 🌸传统程序开发的缺陷
    • 🌸如何解决传统程序的缺陷?
    • 🌸控制反转式程序开发
    • 🌸对比总结
  • 🌲理解 Spring IoC
  • 🍀DI 概念说明
  • ⭕总结

🎍Spring 是什么?

通过前⾯的学习, 我们知道了Spring是⼀个开源框架, 他让我们的开发更加简单. 他⽀持⼴泛的应⽤场
景, 有着活跃⽽庞⼤的社区, 这也是Spring能够⻓久不衰的原因.

但是这个概念相对来说, 还是⽐较抽象.

我们⽤⼀句更具体的话来概括Spring, 那就是: Spring 是包含了众多⼯具⽅法的 IoC 容器

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

🎄什么是IoC呢?

Spring 也是⼀个容器,Spring 是什么容器呢?Spring 是⼀个 IoC 容器。

我们想想,之前课程我们接触的容器有哪些?
• List/Map -> 数据存储容器
• Tomcat -> Web 容器

IoC = Inversion of Control 翻译成中⽂是“控制反转”的意思,也就是说 Spring 是⼀个“控制反转”的容器,怎么理解这句话呢,我们先从以下示例开始

接下来我们通过案例来了解⼀下什么是IoC
需求: 造⼀辆⻋

🌸传统程序开发

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

先设计轮⼦(Tire),然后根据轮⼦的⼤⼩设计底盘(Bottom),接着根据底盘设计⻋⾝(Framework),最
后根据⻋⾝设计好整个汽⻋(Car)。这⾥就出现了⼀个"依赖"关系:汽⻋依赖⻋⾝,⻋⾝依赖底盘,底
盘依赖轮⼦.
在这里插入图片描述
最终程序的实现代码如下:

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("Car init....");
 }
 public void run(){
 System.out.println("Car run...");
 }
 }
 /**
 * ⻋⾝类
 */
 static class Framework {
 private Bottom bottom;
 public Framework() {
 bottom = new Bottom();
 System.out.println("Framework init...");
 }
 }
 /**
 * 底盘类
 */
 static class Bottom {
 private Tire tire;
 public Bottom() {
 this.tire = new Tire();
 System.out.println("Bottom init...");
 }
 }
 /**
 * 轮胎类
 */
 static class Tire {
 // 尺⼨
 private int size;
 public Tire(){
 this.size = 17;
 System.out.println("轮胎尺⼨:" + size);
 }
 }
}

🌸传统程序开发的缺陷

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

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

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

public class NewCarExample {
 public static void main(String[] args) {
 Car car = new Car(20);
 car.run();
 }
 /**
 * 汽⻋对象
 */
 static class Car {
 private Framework framework;
 public Car(int size) {
 framework = new Framework(size);
 System.out.println("Car 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("Framework init...");
 }
 }
 /**
 * 底盘类
 */
 static class Bottom {
 private Tire tire;
 public Bottom(int size) {
 this.tire = new Tire(size);
 System.out.println("Bottom init...");
 }
 }
 /**
 * 轮胎类
 */
 static class Tire {
 // 尺⼨
 private int size;
 public Tire(int size){
 this.size = size;
 System.out.println("轮胎尺⼨:" + size);
 }
 }
}

从以上代码可以看出,以上程序的问题是:当最底层代码改动之后,整个调⽤链上的所有代码都需要
修改.
程序的耦合度⾮常⾼(修改⼀处代码, 影响其他处的代码修改)

🌸如何解决传统程序的缺陷?

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

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

解耦指的是解决了代码的耦合性,耦合性也可以换⼀种叫法叫程序相关性。好的程序代码的耦合性(代码之间的相关性)是很低的,也就是代码之间要实现解耦这就好⽐我们打造⼀辆完整的汽⻋,如果所有的配件都是⾃⼰造,那么当客户需求发⽣改变的时候,⽐如轮胎的尺⼨不再是原来的尺⼨了,那我们要⾃⼰动⼿来改了,但如果我们是把轮胎外包出去,那么即使是轮胎的尺⼨发⽣变变了,我们只需要向代理⼯⼚下订单就⾏了,我们⾃身是不需要出⼒的。

🌸控制反转式程序开发

基于以上思路,我们把调⽤汽⻋的程序示例改造⼀下,把创建⼦类的⽅式,改为注⼊传递的⽅式,具体实现代码如下:class Car

public class IocCarExample {
 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(framework);
 car.run();
 }
 static class Car {
 private Framework framework;
 public Car(Framework framework) {
 this.framework = framework;
 System.out.println("Car init....");
 }
 public void run() {
 System.out.println("Car run...");
 }
 }
 static class Framework {
 private Bottom bottom;
 public Framework(Bottom bottom) {
 this.bottom = bottom;
 System.out.println("Framework init...");
 }
 }
 static class Bottom {
 private Tire tire;
 public Bottom(Tire tire) {
 this.tire = tire;
 System.out.println("Bottom init...");
 }
 }
 static class Tire {
 private int size;
 public Tire(int size) {
 this.size = size;
 System.out.println("轮胎尺⼨:" + size);
 }
 }
}

代码经过以上调整,⽆论底层类如何变化,整个调⽤链是不⽤做任何改变的,这样就完成了代码之间
解耦,从⽽实现了更加灵活、通⽤的程序设计了。

🌸对比总结

在传统的代码中对象创建顺序是:Car -> Framework -> Bottom -> Tire
改进之后解耦的代码的对象创建顺序是:Tire -> Bottom -> Framework -> Car
在这里插入图片描述
我们发现了⼀个规律,通⽤程序的实现代码,类的创建顺序是反的,传统代码是 Car 控制并创建了
Framework,Framework 创建并创建了 Bottom,依次往下,⽽改进之后的控制权发⽣的反转,不再是使⽤⽅对象创建并控制依赖对象了,⽽是把依赖对象注⼊将当前对象中,依赖对象的控制权不再由
当前类控制了.

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

学到这⾥, 我们⼤概就知道了什么是控制反转了, 那什么是控制反转容器呢, 也就是IoC容器
在这里插入图片描述

🌲理解 Spring IoC

Spring 是包含了多个⼯具⽅法的 IoC 容器
具备的基础功能:

  • 将对象存⼊到容器;

  • 从容器中取出对象。

也就是说学 Spring 最核⼼的功能,就是学如何将对象存⼊到 Spring 中,再从 Spring 中获取对象的过程

Spring 是⼀个 IoC 容器,说的是对象的创建和销毁的权利都交给 Spring 来管理了,它本身⼜具备了存储对象和获取对象的能⼒

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

资源不由使⽤资源的双⽅管理,⽽由不使⽤资源的第三⽅管理,这可以带来很多好处。第⼀,资源集
中管理,实现资源的可配置和易管理。第⼆,降低了使⽤资源双⽅的依赖程度,也就是我们说的耦合
度。

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

🍀DI 概念说明

说到 IoC 不得不提的⼀个词就是“DI”,DI 是 Dependency Injection 的缩写,翻译成中⽂是“依赖注⼊”的意思。

所谓依赖注⼊,就是由 IoC 容器在运⾏期间,动态地将某种依赖关系注⼊到对象之中。所以,依赖注⼊(DI)和控制反转(IoC)是从不同的⻆度的描述的同⼀件事情,就是指通过引⼊ IoC 容器,利⽤依赖关系注⼊的⽅式,实现对象之间的解耦。

IoC 是“⽬标”也是⼀种思想,⽽⽬标和思想只是⼀种指导原则,最终还是要有可⾏的落地⽅案,⽽ DI就属于具体的实现

⭕总结

感谢大家的阅读,希望得到大家的批评指正,和大家一起进步,与君共勉!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kafka学习笔记01【2024最新版】

一、Kafka-课程介绍 官网地址:Apache KafkaApache Kafka: A Distributed Streaming Platform.https://kafka.apache.org/ kafka 3.6.1版本,作为经典分布式订阅、发布的消息传输中间件,kafka在实时数据处理、消息队列、流处理等领域具有广泛…

检测水箱水位传感器有哪些?

生活中很多家电中都内含一个水箱,例如电蒸锅、饮水机、蒸汽熨斗、咖啡机等等,这些内部都有水箱,或大或小。当然水箱也有很多种类型,例如生活水箱、生产水箱、消防水箱等等。 把水储存在水箱中也会遇到这些问题,水箱没…

JavaScript云LIS系统源码 前端框架JQuery+EasyUI+后端框架MVC+SQLSuga大型医院云LIS检验系统源码 可直接上项目

JavaScript云LIS系统源码 前端框架JQueryEasyUI后端框架MVCSQLSuga大型医院云LIS检验系统源码 可直接上项目 云LIS系统概述: 云LIS是为区域医疗提供临床实验室信息服务的计算机应用程序,可协助区域内所有临床实验室相互协调并完成日常检验工作&#xff…

pytest-asyncio:协程异步测试案例

简介:pytest-asyncio是一个pytest插件。它便于测试使用异步库的代码。具体来说,pytest-asyncio提供了对作为测试函数的协同程序的支持。这允许用户在测试中等待代码。 历史攻略: asyncio并发访问websocket Python:协程 - 快速创…

SVGDreamer: 文本引导矢量图形合成

现有的 Text-to-SVG 方法还存在两个限制:1.生成的矢量图缺少编辑性;2. 难以生成高质量和多样性的结果。为了解决这些限制,作者提出了一种新的文本引导矢量图形合成方法:SVGDreamer。 论文题目: SVGDreamer: Text Guid…

《Git---Windows Powershell提交信息中文乱码解决方案》

解释: Windows PowerShell中的Git乱码通常是因为字符编码不正确或Git配置不支持Windows系统的默认编码导致的。Git在处理文件时可能使用UTF-8编码,而Windows系统的命令行工具(如PowerShell)默认使用的是Windows-1252或GBK编码。 …

【库函数】Linux下动态库.so和静态库.a的生成和使用

目录 🌞1. Linux下静态库和动态库的基本概念 🌞2. 动态库 🌊2.1 动态库如何生成 🌍2.1.1 文件详情 🌍2.1.2 编译生成动态库 🌊2.2 动态库如何使用 🌍2.2.1 案例 🌍2.2.2 动态…

TCP详解

2.1TCP 由IETF的RFC793定义的传输控制协议(Transmission Control Protocol,TCP)是一种基于字节流的传输层通信协议。在传输数据前需要在发送与接收者之间建立连接,通过相应机制保证其建立连接的可靠性。 TCP协议具备以下特性&am…

云备份项目->配置环境

升级gcc到7.3版本 sudo yum install centos-release-scl-rh centos-release-scl sudo yum install devtoolset-7-gcc devtoolset-7-gcc-c source /opt/rh/devtoolset-7/enable echo "source /opt/rh/devtoolset-7/enable" >> ~/.bashrc 安装Jsoncpp库 sud…

十、多模态大语言模型(MLLM)

1 多模态大语言模型(Multimodal Large Language Models) 模态的定义 模态(modal)是事情经历和发生的方式,我们生活在一个由多种模态(Multimodal)信息构成的世界,包括视觉信息、听觉信息、文本信息、嗅觉信…

STM32与Proteus的串口仿真详细教程与源程序

资料下载地址:STM32与Proteus的串口仿真详细教程与源程序 资料内容 包含LCD1602显示,串口发送接收,完美实现。 文档内容齐全,包含使用说明,相关驱动等。 解决了STM32的Proteus串口收发问题。 注意:每输…

IP-guard getdatarecord 存在任意文件读取

声明 本文仅用于技术交流,请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。 一、产品介绍 IP-guard是由溢信科技股份有限公司开发的一款终端安全管…

揭秘被忽视的商业模式:全民拼购助力客户实现日销千万的惊人业绩

今天,我想和大家分享一个颇具潜力的模式与玩法,尽管它在外界看来可能略显陈旧。这个模式曾被忽视,但我的一位客户却巧妙运用,实现了惊人的业绩——日销售额接近五千万,日订单量高达300万单。 值得注意的是,…

一键搞定COX回归亚组森林图!快速生成顶级SCI论文的高清图!

现在亚组分析好像越来越流行,无论是观察性研究还是RCT研究,亚组分析一般配备森林图。 比如NEJM这张图: 比如Lancet这张图: 但是在使用R语言绘制时,简单的代码画不出好看的图,好看的图又需要许多代码参数来进…

[HUBUCTF 2022 新生赛]最简单的misc

有点简单, 要用到工具lsb,qr扫码 一般杂项先binwalk,不行的话在lsb 因为头是png所以save bin出二维码,用QR扫码 即可得出flag

知识分享之cookie

http协议中的cookie,什么是cookie如何获取cookie 一、什么是Cookie Cookie(曲奇,小甜饼的译名)在互联网技术领域中,是指一种小型文本文件,它由网站服务器发送给用户的浏览器,并被浏览器存储在用…

Linux--自主编写shell

目录 准备知识 shell原理 shell与用户互动的过程 实现shell 0.用到的头文件和宏定义 1.首先我们需要自己输出一个命令行 2.获取用户命令行字符 3.命令行字符串分割 4.执行命令 5.设置循环 6.检测内建命令 7.完善细节--获取工作目录而非路径 准备知识 Linux--环境…

太速科技-基于6 U VPX M.2 高带宽加固存储板

基于6 U VPX M.2 高带宽加固存储板 一、板卡概述 基于6 U VPX M.2 高带宽加固存储板,可以实现VPX接口的数据读写到PCI-E总线的NVME存储媒介上。采用PLX8732,上行链路提供带宽x16的PCI-E数据到VPX接口上;下行链路提供3路带宽x4的PCI-E接口…

重生之我是Nginx服务专家

nginx服务访问页面白色 问题描述 访问一个域名服务返回页面空白,非响应404。报错如下图。 排查问题 域名解析正常,网络通讯正常,绕过解析地址访问源站IP地址端口访问正常,nginx无异常报错。 在打开文件时,发现无法…

(学习日记)2024.05.04:UCOSIII第五十八节:User文件夹函数概览(uCOS-III->Source文件夹)第四部分

写在前面: 由于时间的不足与学习的碎片化,写博客变得有些奢侈。 但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。 既然如此 不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录&a…