【Spring】什么是Spring?
什么是Spring?
Spring是一个开源的轻量级框架,是为了简化企业级开发而设计的。我们通常讲的Spring一般指的是Spring Framework。Spring的核心是控制反转(IoC-Inversion of Control)和面向切面编程(AOP-Aspect-Oriented Programming)。这些功能使得开发者可以专注于业务逻辑的实现,不用去关注底层的实现。除此之外,Spring还可以与第三方库和框架集成,如Mybatis等,使得我们开发更加方便。
我们来看看官方的解释:
Spring | Why Spring
可以看到,spring包含了很多模块,简单来说:Spring是包含了很多工具方法的IoC容器。
什么是容器?
Spring容器是Spring框架中的核心组成部分,负责管理Spring Bean的生命周期和依赖关系,Spring容器是一个BeanFactory(Bean工厂),负责实例化、配置和管理Bean。
在Spring程序中,我们所有的Bean都是存放在容器中,通过IoC(控制反转)技术进行管理。Spring容器通过自动装配(autowiring)的方式将各个Bean之间建立联系,从而减少手动配置的工作量。同时,Spring容器还提供了丰富的扩展机制,使得开发者可以根据自己的需求对bean进行定制化配置。
什么是IoC?
Spring IoC(控制反转),是一种设计思想,通过将对象的创建和管理权交给了Spring容器,降低了程序之间的耦合性,
在Spring框架中,IoC主要通过XML配置文件、注解或Java配置等方式实现。通过使用IoC,应用程序的各个模块之间就可以以低耦合的形式进行协同工作,提高应用程序的可扩展性和可维护性。
传统程序开发流程
我们来举个例子,来更好的理解上面所述内容。
假设我们现在要生产一辆车,其基本思路如下:
按照传统的做法,我们生产一辆车,车的构成需要依赖车身(Framework),而车身需要依赖底盘(Bottom),底盘需要依赖轮胎(Tire)。
按照这种思路,我们用代码实现如下:
public class CarProduct {public static void main(String[] args) {Car car = new Car();car.init();}/*** 汽车对象*/static class Car {private Framework framework;public Car() {framework = new Framework();}public void init() {framework.init();}}/*** 车身Framework*/static class Framework {private Bottom bottom;public Framework() {bottom = new Bottom();}public void init() {bottom.init();}}/*** 底盘Bottom*/static class Bottom {private Tire tire;public Bottom() {tire = new Tire();}public void init() {tire.init();}}/*** 轮胎Tire*/static class Tire {private int size = 20;//轮胎大小public void init() {System.out.println("轮胎大小:" + size);}}
}
我们可以看到,在上面的代码中,轮胎的尺寸是固定的,但是现在车的数量非常多,车轮胎的尺寸不可能都是一样的,所以我们就需要生产出各种尺寸大小的轮胎。我们需要对上面的代码进行修改:
public class CarProduct {public static void main(String[] args) {Car car = new Car();car.init(10);}/*** 汽车对象*/static class Car {private Framework framework;public Car() {framework = new Framework();}public void init(int size) {framework.init(size);}}/*** 车身Framework*/static class Framework {private Bottom bottom;public Framework() {bottom = new Bottom();}public void init(int size) {bottom.init(size);}}/*** 底盘Bottom*/static class Bottom {private Tire tire;public Bottom() {tire = new Tire();}public void init(int size) {tire.init(size);}}/*** 轮胎Tire*/static class Tire {public void init(int size) {System.out.println("轮胎大小:" + size);}}
}
我们可以看到,虽然满足我们的需求了,但是在上面的代码中,不难看到,当最底层的代码修改后,整个调用链上的代码都需要进行修改,这样耦合度就非常高了。
那么如果解决上面出现的这种问题呢?
在上面的代码中,我们都是在每个类中创建下一个要调用的类,这样的耦合度就非常高。
那么我们可以不在类中创建下级类,而是改为传递的方式(即注入),这样我们就能实现解耦,下级类的改变发生变化,对于当前类来说,也无需修改任何代码。
解耦指的是:解决了代码之间的依赖程度,也可以叫做程序相关性,好的程序的代码的耦合性是很低的,也就是代码之间要解耦。
这就好比我们生产一辆汽车,如果所有的配件都是自己制造的,那么当客户要改变需求时,如,客户想要一个比较大的轮胎,那么我们就需要自己生产,这样的效率是非常低的,但如果我们把轮胎的生产外包出去,那么就算轮胎的尺寸要发生改变,我们也能向代理公厂下单即可,无需自己生产,这样效率就提高了不少。
控制反转程序开发流程(IoC)
根据上面所述,对代码进行修改:
*** CarProduct类是汽车生产模型的示例,展示了如何通过组合不同类来构建复杂的对象结构*/
public class CarProduct {/*** 程序的入口点* 创建汽车对象及其组成部分,并初始化* @param args 命令行参数*/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.init();}/*** 汽车对象*/static class Car {private Framework framework;/*** 构造方法,初始化汽车的车身* @param framework 汽车的车身*/public Car(Framework framework) {this.framework = framework;}/*** 初始化汽车对象,包括其车身*/public void init() {framework.init();}}/*** 车身Framework*/static class Framework {private Bottom bottom;/*** 构造方法,初始化车身的底盘* @param bottom 车身的底盘*/public Framework(Bottom bottom) {this.bottom = bottom;}/*** 初始化车身对象,包括其底盘*/public void init() {bottom.init();}}/*** 底盘Bottom*/static class Bottom {private Tire tire;/*** 构造方法,初始化底盘的轮胎* @param tire 底盘的轮胎*/public Bottom(Tire tire) {this.tire = tire;}/*** 初始化底盘对象,包括其轮胎*/public void init() {tire.init();}}/*** 轮胎Tire*/static class Tire {private int size;//轮胎大小/*** 构造方法,初始化轮胎的大小* @param size 轮胎的大小*/public Tire(int size) {this.size = size;}/*** 初始化轮胎对象,打印轮胎大小*/public void init() {System.out.println("轮胎大小:" + size);}}
}
我们可以看到,通过上面的修改,就算底层类发生变化,整个调用链的代码也是不用做任何修改的,这样就实现代码之间的解耦,从而提高了代码的灵活性、复用性。
我们来对比一下传统程序开发流程和控制反转程序开发流程:
我们可以看到,传统的开发流程是:Car依赖Framework,Framework依赖Bottom,...。而在改进之后的代码中,控制权发生了反转,不再是由上级对象创建下级对象并控制下级对象,而是下级对象注入到上级对象中,下级对象不再受上级对象的控制,这样就算下级对象发生改变,也不会影响到上级对象,这就是典型的控制反转,也就是IoC的实现思想。
如何理解Spring IoC
在以往的程序设计中,对象之间的依赖关系通常是由程序内部通过new关键字来实现的,这样的方式,会导致程序内部与具体实现的对象紧密联系(即耦合度高),一旦对象的实现发生改变,那么对于程序中的一部分代码也需要进行修改,这不仅增加了开发成本,而且也增加了代码的维护难度。
Spring IoC则是将对象的创建和管理权交给了Spring容器。在Spring容器中,所有的对象称为Bean,并通过配置文件或注解等方式来进行获取对象。当程序某处需要用到Bean对象时,Spring容器就会负责查找、创建、注入Bean对象。而程序本身不需要关心Bean对象时如何实例化和管理的。这种方式的创建和管理权从原先的程序中转移到Spring容器中,从而实现了控制反转(IoC)。
Spring IoC的优点
- 降低耦合度:通过把对象的实例和管理权交给Spring容器,从而让程序与对象之间的耦合性降低,使得代码更加灵活、可维护、可复用。
- 提高可扩展性:由于对象的创建和管理权交给了Spring容器,当我们需要添加新的功能或模块时,我们只需要在Spring中注册相应的bean即可。
- 简化开发:使用Spring IoC可以简化开发。开发者只需要关注业务逻辑的实现,而不需要花费过多的精力在对象的创建和管理上。
- 提高性能:虽然使用Spring IoC会增加一些额外的开销,但在大多数情况下,这种开销是微不足道的。而且,通过使用Spring IoC,可以减少不必要的对象创建和销毁,从而提高应用程序的性能。
DI(依赖注入)
DI(Dependcy Injection,即依赖注入)是一种软件设计模式,用于实现松耦合和可测试性的代码结构。在寻常的编程中,对象通常自己负责创建和管理它锁依赖的其他对象,这样导致了对象之间的耦合度高,使得对象难以复用和测试。
而DI是一种实现控制反转(Inversion of Control,简称 IoC)的机制。它允许对象之间的依赖关系由外部容器(Spring 容器)来管理,而不是由对象自身来创建或查找依赖对象。这种方式可以减少对象之间的耦合性,提高代码的可重用性和可维护性。
DI的实现方式
DI的主要实现方式包括构造函数注入、属性注入和方法注入。
- 构造函数注入是最常见的DI方式,它通过在对象的构造函数中传递依赖对象来实现。
- 属性注入是通过设置对象的属性来注入依赖对象。
- 方法注入是一种更灵活的DI方式,它通过在对象的方法中传递依赖对象来实现。
DI的优点
- 降低耦合度:DI使得对象之间的耦合度降低,因为对象不直接创建依赖,而是通过外部注入的方式获得。这使得每个对象更加独立,更易于管理和维护。
- 提高代码的可维护性:由于对象之间的耦合度降低,修改一个对象时对其他对象的影响也会减少,这使得代码更易于维护和升级。
- 提高灵活性:DI使得对象的依赖关系可以动态地管理和修改,这使得代码更加灵活,可以根据实际需求进行修改和扩展。
- 增强代码的可测试性:依赖注入使得单元测试变得更加容易。开发者可以通过注入模拟(mock)对象或存根(stub)来测试组件的行为,而不需要依赖于实际的依赖对象。
- 提高代码的可重用性:由于对象不依赖于具体的实现,而是依赖于抽象(接口或抽象类),因此可以更容易地替换对象的实现,从而提高代码的可重用性。
Spring相关网站
Spring官方网站:Spring | Homehttps://spring.io/https://spring.io/https://spring.io/
Spring Framework官方文档:Spring Framework 文档 :: Spring Frameworkhttps://docs.spring.io/spring-framework/reference/https://docs.spring.io/spring-framework/reference/https://docs.spring.io/spring-framework/reference/
Spring Boot官方文档:Spring Boot :: Spring Boothttps://docs.spring.io/spring-boot/index.htmlhttps://docs.spring.io/spring-boot/index.htmlhttps://docs.spring.io/spring-boot/index.html
Spring Cloud官方文档:Spring Cloudhttps://spring.io/projects/spring-cloud#learnhttps://spring.io/projects/spring-cloud#learnhttps://spring.io/projects/spring-cloud#learn
Spring源代码仓库:Spring · GitHubhttps://github.com/spring-projectshttps://github.com/spring-projectshttps://github.com/spring-projects
Spring源代码仓库中文文档:Spring Framework 中文文档https://www.docs4dev.com/docs/zh/spring-framework/5.1.3.RELEASE/reference/https://www.docs4dev.com/docs/zh/spring-framework/5.1.3.RELEASE/reference/https://www.docs4dev.com/docs/zh/spring-framework/5.1.3.RELEASE/reference/
Spring Boot中文文档:Spring Boot 参考https://www.docs4dev.com/docs/spring-boot/2.4.6/reference/getting-started.html#getting-startedhttps://www.docs4dev.com/docs/spring-boot/2.4.6/reference/getting-started.html#getting-startedhttps://www.docs4dev.com/docs/spring-boot/2.4.6/reference/getting-started.html#getting-started
Spring Cloud中文文档:Spring Cloud 中文文档https://www.docs4dev.com/docs/zh/spring-cloud/Finchley.SR2/reference/https://www.docs4dev.com/docs/zh/spring-cloud/Finchley.SR2/reference/https://www.docs4dev.com/docs/zh/spring-cloud/Finchley.SR2/reference/
以上就是本篇所有内容啦~
若有不足,欢迎指正~
相关文章:

【Spring】什么是Spring?
什么是Spring? Spring是一个开源的轻量级框架,是为了简化企业级开发而设计的。我们通常讲的Spring一般指的是Spring Framework。Spring的核心是控制反转(IoC-Inversion of Control)和面向切面编程(AOP-Aspect-Oriented Programming)。这些功能使得开发者…...

全面理解-c++11中的智能指针
在 C 中,智能指针(Smart Pointers) 是用于自动管理动态分配内存的类模板,遵循 RAII(Resource Acquisition Is Initialization) 原则,确保资源在生命周期结束时被正确释放,避免内存泄…...

【jmeter】在windows中,创建的变量,在jmeter中,读取变量失败的问题,路径问题
1.0 在windows中,jmeter读取变量失败 在路径配置的时候,配置按照D:\FtpDownload\${file_name}运行之后,下载的文件,文件名出现问题 \取消了$符号的意义,所以需要更改路径 D:\\FtpDownload\\${file_name}...

【CubeMX-HAL库】STM32F407—无刷电机学习笔记
目录 简介: 学习资料: 跳转目录: 一、工程创建 二、板载LED 三、用户按键 四、蜂鸣器 1.完整IO控制代码 五、TFT彩屏驱动 六、ADC多通道 1.通道确认 2.CubeMX配置 ①开启对应的ADC通道 ②选择规则组通道 ③开启DMA ④开启ADC…...

使用 POI-TL 和 JFreeChart 动态生成 Word 报告
文章目录 前言一、需求背景二、方案分析三、 POI-TL JFreeChart 实现3.1 Maven 依赖3.3 word模板设置3.2 实现代码 踩坑 前言 在开发过程中,我们经常需要生成包含动态数据和图表的 Word 报告。本文将介绍如何结合 POI-TL 和 JFreeChart,实现动态生成 W…...

xxl-job的分片广播
目录 xxl-job的分片广播 场景引入 xxl-job简介 xxl-job的部署安装 代码编写 1.导入依赖 2.yml文件编写 3.编写xxl-job执行器配置类,维护一个xxl-job执行器的bean 4.编写第一个任务,任务名字叫firstJob 5.进入服务端,增加执行器和任务…...

MobaXterm破解会话上限限制
1. 下载安装包MobaXterm-Keygen 下载路径: https://gitcode.com/gh_mirrors/mob/MobaXterm-Keygen 2. 搭建python3环境 window下python3环境搭建可参考网站: https://blog.csdn.net/enteracity/article/details/135479689 3. 生成文件Custom.mxtpro…...

vscode设置保存时自动缩进和格式化
参考博客 如何在 VSCode 中自动缩进你的代码 | Linux 中国 省流 使用 Ctrl Shift P 来打开命令模式,搜索 Open User Settings 并按下回车你需要搜索 Auto Indent,并在 “编辑器:自动缩进(Editor: Auto Indent)” 中选择 “全部(Full)”P…...

一键查看电脑各硬件详细信息 轻松查看电脑硬件参数
今天为大家推荐两款非常实用的电脑硬件查看软件,它们能够一键快速查看电脑的各种配置信息,使用起来非常方便。 一键查看电脑各硬件详细信息 这款软件是绿色版的,无需安装,打开即可使用,文件大小仅为900多KB࿰…...

【C++11】lambda和包装器
1.新的类功能 1.1默认的移动构造和移动赋值 原来C类中,有6个默认成员函数:构造函数/析构函数/拷⻉构造函数/拷⻉赋值重载/取地址重 载/const 取地址重载,最后重要的是前4个,后两个⽤处不⼤,默认成员函数就是我们不写…...

react redux用法学习
参考资料: https://www.bilibili.com/video/BV1ZB4y1Z7o8 https://cn.redux.js.org/tutorials/essentials/part-5-async-logic AI工具:deepseek,通义灵码 安装相关依赖: 使用redux的中间件: npm i react-reduxreact-…...

前端HTML标签 meta中常见的一些属性
meta中常见的一些属性 <meta/> 标签的属性 <meta/> 是什么? <meta/> 标签主要用于表示和当前文档相关的 元数据 信息。 而 元数据(metadata),简单的来说就是描述数据的数据。例如,一个 HTML 文件是一…...

127,【3】 buuctf [NPUCTF2020]ReadlezPHP
进入靶场 吓我一跳 查看源码 点击 审计 <?php// 定义一个名为 HelloPhp 的类,该类可能用于执行与日期格式化相关的操作 class HelloPhp {// 定义一个公共属性 $a,用于存储日期格式化的模板public $a;// 定义一个公共属性 $b,用于存储…...

继承(python)
一、基础知识 (一)定义:子类能继承父类所有的公有属性和公有方法(先使用子类的方法、属性) (二)格式: class 子类名(父类名): #父类 class Ph…...

驱动开发系列36 - Linux Graphics 2D 绘制流程
一: 概述 在Linux中,2D绘制流程是操作系统、图形库、显示协议、驱动程序等多个组件协调工作的结果。整体流程如下步骤所示: 1. 客户端请求:客户端程序(如GTK、Qt应用程序)通过X11协议与Xorg-Server通信(或通过Wayland协议与Wayland合成器通信)、请求绘制2D图形,比如绘制…...

STL函数算法笔记
STL函数算法笔记 今天我们来学习的是STL库中的一些函数。首先,STL这个东西大家一定非常熟悉,里面很多的数据结构都帮了大家不少忙,那么今天我们就来说几个重要的数据结构。 向量 向量,也就是数据结构vector,你也可以称之为动态数组,本质跟数组差不多,只不过有一些好处…...

【Vue】在Vue3中使用Echarts的示例 两种方法
文章目录 方法一template渲染部分js部分方法一实现效果 方法二template部分js or ts部分方法二实现效果 贴个地址~ Apache ECharts官网地址 Apache ECharts示例地址 官网有的时候示例显示不出来,属于正常现象,多进几次就行 开始使用前,记得先…...

小红书自动化:如何利用Make批量生成爆款笔记
小红书自动化:如何利用Make制作个人自媒体中心,批量生成爆款笔记 引言 在如今信息爆炸的时代,如何高效地获取和分享优质内容,成为了每位自媒体工作者必须面对的挑战。你是否想过,如果能够将这项繁复的工作实现自动化…...

学习率调整策略 | PyTorch 深度学习实战
前一篇文章,深度学习里面的而优化函数 Adam,SGD,动量法,AdaGrad 等 | PyTorch 深度学习实战 本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started 本篇文章内容来自于 强化学习必修课:引…...

DeepSeekMoE 论文解读:混合专家架构的效能革新者
论文链接:DeepSeekMoE: Towards Ultimate Expert Specialization in Mixture-of-Experts Language Models 目录 一、引言二、背景知识(一)MoE架构概述(二)现有MoE架构的问题 三、DeepSeekMoE架构详解(一&a…...

以下是基于巨控GRM241Q-4I4D4QHE模块的液位远程控制系统技术方案:
以下是基于巨控GRM241Q-4I4D4QHE模块的液位远程控制系统技术方案: 一、系统概述 本系统采用双巨控GRM241Q模块构建4G无线物联网络,实现山上液位数据实时传输至山下水泵站,通过预设逻辑自动控制水泵启停,同时支持APP远程监控及人工…...

【JVM详解五】JVM性能调优
示例: 配置JVM参数运行 #前台运行 java -XX:MetaspaceSize-128m -XX:MaxMetaspaceSize-128m -Xms1024m -Xmx1024m -Xmn256m -Xss256k -XX:SurvivorRatio8 - XX:UseConcMarkSweepGC -jar /jar包路径 #后台运行 nohup java -XX:MetaspaceSize-128m -XX:MaxMetaspaceS…...

2.10日学习总结
题目一: AC代码 #include <stdio.h>#define N 1000000typedef long long l;int main() {int n, m;l s 0;l a[N 1], b[N 1];int i 1, j 1;scanf("%d %d", &n, &m);for (int k 1; k < n; k) {scanf("%lld", &a[k]);…...

疯狂前端面试题(四)
一、Ajax、JSONP、JSON、Fetch 和 Axios 技术详解 1. Ajax(异步 JavaScript 和 XML) 什么是 Ajax? Ajax 是一种用于在不刷新页面的情况下与服务器进行数据交互的技术。它通过 XMLHttpRequest 对象实现。 优点 - 支持同步和异步请求。 - 能…...

YOLOv11-ultralytics-8.3.67部分代码阅读笔记-metrics.py
metrics.py ultralytics\utils\metrics.py 目录 metrics.py 1.所需的库和模块 2.def bbox_ioa(box1, box2, iouFalse, eps1e-7): 3.def box_iou(box1, box2, eps1e-7): 4.def bbox_iou(box1, box2, xywhTrue, GIoUFalse, DIoUFalse, CIoUFalse, eps1e-7): 5.def mas…...

SuperCopy解除网页禁用复制功能插件安装和使用
点击下载《SuperCopy解除网页禁用复制功能插件》 1. 前言 在当今数字化时代,网络已成为我们获取信息和知识的主要渠道。互联网如同一片浩瀚无垠的知识海洋,蕴藏着无数的资源,从学术论文到生活小窍门,从专业教程到娱乐资讯&#…...

UP-VLA:具身智体的统一理解与预测模型
25年1月来自清华大学和上海姚期智研究院的论文“UP-VLA: A Unified Understanding and Prediction Model for Embodied Agent”。 视觉-语言-动作 (VLA) 模型的最新进展,利用预训练的视觉语言模型 (VLM) 来提高泛化能力。VLM 通常经过视觉语言理解任务的预训练&…...

Unity 基于状态机的逻辑控制详解
状态机是游戏开发中常用的逻辑控制方法,它可以将复杂的逻辑分解成多个独立的状态,并通过状态转移来控制逻辑的执行流程。本文将详细介绍如何在 Unity 中基于状态机实现逻辑控制,并提供技术详解和代码实现。 一、状态机简介 1.1 基本概念 状…...

傅里叶单像素成像技术研究进展
摘要:计算光学成像,通过光学系统和信号处理的有机结合与联合优化实现特定成像特性的成像系统,摆脱了传统成像系统的限制,为光学成像技术添加了浓墨重彩的一笔,并逐步向简单化与智能化的方向发展。单像素成像(Single-Pi…...

IDEA接入DeepSeek
IDEA 目前有多个途径可以接入deepseek,比如CodeGPT或者Continue,这里借助CodeGPT插件接入,CodeGPT目前用的人最多,相对更稳定 一、安装 1.安装CodeGPT idea插件市场找到CodeGPT并安装 2.创建API Key 进入deepseek官网…...