1. Spring 核心与设计思想

目录

1. Spring 是什么?

1.1 什么是容器?

1.2 什么是 Ioc ?

1.2.1 传统程序开发

1.2.2 解决传统开发的缺陷

1.2.3 控制反转式程序开发

1.2.4 IoC 的实现思想(重点)

1.3 理解 Spring Ioc

1.4 DI 概念说明


1. Spring 是什么?

Spring 指的是 Spring Framework (spring 框架),它是一个开源框架,有着活跃而庞大的社区,这就是它之所以能长久不衰的原因。

Spring 是包含了众多工具方法的 IoC 容器。

1.1 什么是容器?

容器是用来容纳某种物品的装置。

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

1.2 什么是 Ioc ?

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

1.2.1 传统程序开发

是通过一层一层的依赖实现的。比如我们要构建一辆车,需要依赖车身,车身进而需要依赖底盘,底盘又需要依赖轮胎。因此一般的实现代码如下:

在 NewCarUpateExample 类中:

public class NewCarUpateExample {public static void main(String[] args) {Car car = new Car();car.init();}
}

 首先,我们先创建一个汽车对象:

/*** 汽车对象*/
public class Car {public void init(){// 依赖车身Framework framework = new Framework();framework.init();}
}

由于汽车对象需要依赖车身,因此我们创建一个车身类:

/*** 车身类*/
public class Framework {public void init(){// 依赖底盘Bottom bottom = new Bottom();bottom.init();}
}

又因为车身依赖于底盘,因此创建底盘类:

/*** 底盘类*/
public class Bottom {public void init(){// 依赖轮胎Tire tire = new Tire();tire.init();}
}

最后,因为底盘依赖于轮胎,因此创建轮胎类:

/*** 轮胎类*/
public class Tire {// 轮胎尺寸private int size = 30;public void init(){System.out.println("轮胎尺寸" + size);}
}

在以上程序中,轮胎的尺寸是固定的,但是实际中根据各种需求,轮胎的尺寸也会发生变化,因此修改代码如下:

在 NewCarUpateExample 类中:

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

从以上代码可以看出:当最底层的代码修改后,其他层的代码均需要进行修改。

1.2.2 解决传统开发的缺陷

如何解决代码之间的耦合性过高的问题呢?

我们只需要将原来自己创建的下级类,改为传递的方式(也就是注入),因为我们不需要在当前类中创建下级类,所以下级类发生变化时,当前类本身就无需再进行修改,这样就完成了程序的解耦

1.2.3 控制反转式程序开发

接下来,在上述程序的基础上,我们将创建子类的方式改为注入传递的方式。

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();}
}
/*** 汽车对象*/
public class Car {private Framework framework;public Car(Framework framework){this.framework = framework;}public void run(){// 依赖车身framework.init();}
}
/*** 车身类*/
public class Framework {private Bottom bottom;public Framework(Bottom bottom){this.bottom = bottom;}public void init(){// 依赖底盘bottom.init();}
}
/*** 底盘类*/
public class Bottom {private Tire tire;public Bottom(Tire tire){this.tire = tire;}public void init(){// 依赖轮胎tire.init();}
}
/*** 轮胎类*/
public class Tire {// 轮胎尺寸private int size;public Tire(int size){this.size = size;}public void init(){System.out.println("轮胎尺寸" + size);}
}

代码经过以上调整之后,无论底层如何变化,整个调用链是不用做任何改变的,这样就完成了代码之间的解耦

1.2.4 IoC 的实现思想(重点)

在传统代码中对象创建的规律是:Car -> Framework -> Bottom -> TIre

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

改进之后的控制权发生的反转,不再是上级对象创建并控制下级对象了,而是把下级对象注入当前对象中,下级的控制权不再由上级类控制了,这样即使下级类发⽣任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是 IoC 的实现思想 

(对于依赖对象的管理的控制权反转,通过 Spring 来管理对象的生命周期。不是所有的对象都交给 Spring 管理,需要程序来告诉 Spring 管理哪些对象)。

1.3 理解 Spring Ioc

既然 Spring 是⼀个 IoC(控制反转)容器,重点还在“容器”⼆字上,那么它就具备两个最基础的功
能:

  • 将对象存入到容器;
  • 从容器中取出对象。

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

将对象存放到容器中的好处:将对象存储在 IoC 容器相当于将以后可能⽤的所有工具制作好都放到仓库中,需要的时候直接取就行了,用完再把它放回到仓库。而 new 对象的方式相当于,每次需要工具了,才现做,用完就扔掉了也不会保存,下次再⽤的时候还得重新做,这就是 IoC 容器和普通程序开发的区别。

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

1.4 DI 概念说明

DI 是 Dependency Injection 的缩写,即 依赖注入

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

IoC 是“目标”也是⼀种思想,而目标和思想只是⼀种指导原则,最终还是要有可行的落地⽅案,而 DI就属于具体的实现(即 IoC 是思想,DI 是具体实现)。 

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

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

相关文章

【产品设计】通用后台管理系统需求及原型设计

后台管理系统,会根据不同公司、不同业务的要求做出改变。 网上很多系统的参考多数为业务中台,过于带有业务色彩。做过三四个后台管理系统,从中总结了一个通用的功能和需求设计模版,供大家参考。本文适用于0-2岁的产品经理做基础功…

JVM中类加载的过程

文章目录 一、类加载是什么二、类加载过程1.加载2.验证3.准备4.解析5.初始化 三、什么时候进行类加载四、双亲委派模型1.三大类加载器2.加载过程 总 一、类加载是什么 把.class文件加载到内存中,得到类对象的过程。 二、类加载过程 1.加载 找到.class文件&#xff…

【问题解决】VSCode 远程安装插件特别慢

【问题描述】 我要配置 VSCode WSL 的开发环境,需要在 WSL 里也装上 C、CMake 系列的插件,如下图的直接下载方式特别慢: 【解决方法】 先去网站下载插件:https://marketplace.visualstudio.com/,后缀名:…

算法训练营第四十一天||● 343. 整数拆分 96.不同的二叉搜索树

● 343. 整数拆分 这道有难度,不看题解肯定 想不到用动态规划,看了题解后能大概明白,但还不是很清晰,不太明白递推公式中强调的与dp[i]还要比较一次,也不明白第一次去最大最的那个比较 需要后面继续看 动规五部曲&a…

无涯教程-Javascript - Switch语句

从JavaScript 1.2开始,您可以使用 switch 语句来处理这种情况,它比重复的 if ... else if 语句更有效。 流程图 以下流程图说明了switch-case语句的工作原理。 switch 语句的目的是给出一个要求值的表达式,并根据表达式的值执行多个不同的语…

酷开科技大屏营销,撬动营销新增量

5G、人工智能、元宇宙等技术的发展促使数字营销的内容、渠道、传播方式发生了一系列变化;存量竞争下,增长成为企业更加迫切、更具挑战的课题,品牌营销活动越来越围绕“生意增长”和“提效转化”的目标展开。 如今的市场环境下,产…

PID算法

PID,就是“比例(proportional)、积分(integral)、微分(derivative)”,是一种很常见的控制算法。 需要将一个物理量保持在稳定状态(比如维持平衡,温度、转速的…

C#图片处理

查找图片所在位置 原理:使用OpenCvSharp对比查找小图片在大图片上的位置 private static System.Drawing.Point Find(Mat BackGround, Mat Identify, double threshold 0.8) {using (Mat res new Mat(BackGround.Rows - Identify.Rows 1, BackGround.Cols - Iden…

【Matlab】基于BP神经网络的数据回归预测(Excel可直接替换数据)

【Matlab】基于BP神经网络的数据回归预测(Excel可直接替换数据) 1.模型原理2.文件结构3.Excel数据4.分块代码5.完整代码6.运行结果1.模型原理 BP(Backpropagation)回归模型是一种基于反向传播算法的神经网络模型,用于解决回归问题。它通过对输入和输出之间的非线性关系进…

GStreamer Basic tutorial 学习笔记(七)

多线程处理 目标:GStreamer可以自动处理多线程,但在某些情况下,可能需要手动分离线程。 介绍:GStreamer 是一个多线程框架。这意味着在内部,它根据需要创建和销毁线程,例如将流媒体与应用程序线程分离。此…

MongoDB的分布式ID

MongoDB ObjectID是MongoDB数据库中的一种数据类型,用于表示一个文档(document)在集合(collection)中的唯一标识符。每个ObjectID值是一个12字节的字符串,其中前四个字节表示时间戳,后三个字节表…

win10 开机自动启动pyqt做的exe文件,显示后端请求的信息做提醒

1 py 代码 import sys from PyQt5.QtWidgets import QApplication, QWidget, QLabel from PyQt5.QtCore import QTimer import osclass ReminderWindow(QWidget):def __init__(self):super().__init__()self.setWindowTitle(Reminder)self.setGeometry(100, 100, 300, 200)sel…

为什么项目可见性难以实现?该如何提高?

在项目和专业服务管理中,失败有时难以避免。沟通不足和需求定义不明确被认为是造成失败的最大原因,这意味着项目可见性和信息流动至关重要。 什么是项目可见性? 项目可见性是组织项目相关信息的方式,以便所有团队成员、项目经理…

【机器学习】KNN 算法介绍

KNN(K-Nearest Neighbors)算法是一种基本的机器学习算法,用于分类和回归问题。该算法根据样本之间的距离度量,在训练数据集中找到与待分类样本最近邻的K个样本,并基于这K个样本进行分类或回归。 KNN算法的核心思想是“…

spring-cloud-gateway版本和springboot版本不匹配

在搭建gateway服务的时候,启动出现以下问题: Description: An attempt was made to call a method that does not exist. The attempt was made from the following location: org.springframework.cloud.gateway.config.GatewayAutoConfiguration$Netty…

LeetCode 75 第五题(345)反转字符串中的元音字母

题目: 示例: 分析: 给一个字符串,将里面的元音字母反转,并且保持非元音字母不变(包括顺序). 字符串反转类型的题,我们都可以使用双指针来解决:定义首尾指针,分别向中间靠拢,直到首尾指针都指向了元音字母,然后交换首尾指针所指的字母,如此不会影响到非元音字母,同时也将元音字…

2023“钉耙编程”中国大学生算法设计超级联赛(1)Hide-And-Seek Game

2023“钉耙编程”中国大学生算法设计超级联赛(1)Hide-And-Seek Game 题目大意 有一棵有 n n n个节点的树,小 S S S和小 R R R在树上各有一条链。小 S S S的链的起点为 S a S_a Sa​,终点为 T a T_a Ta​;小 R R R的链…

pytest实现用例间参数传递的方式

pytest实现用例间参数传递的方式 一、通过conftest创建全局变量二、使用tmpdir_factory方法 我们在做接口自动化测试的时候,会经常遇到这种场景:接口A的返回结果中的某个字段,是接口B的某个字段的入参。如果是使用postman,那我们可…

CSS:给子元素设置了浮动,页面缩放的时候,子元素往下掉

前言 给子元素设置了浮动&#xff0c;页面缩放的时候&#xff0c;子元素往下掉 html代码&#xff1a; <div class"father"><div class"child1"></div><div class"child2"></div> </div>css代码 .child1…

Spring Batch之读数据库——JdbcCursorItemReader之使用框架提供的BeanPropertyRowMapper(三十六)

一、BeanPropertyRowMapper介绍 参考我的另一篇博客&#xff1a; Spring Batch之读数据库——JdbcCursorItemReader&#xff08;三十五&#xff09;_人……杰的博客-CSDN博客 二、项目实例 1.项目框架 2.代码实现 BatchMain.java: package com.xj.demo27;import org.spri…