【JavaEE进阶】 Spring核⼼与设计思想

文章目录

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

🌲Spring 是什么?

我们通常所说的 Spring 指的是 Spring Framework(Spring 框架),它是⼀个开源框架,有着活跃⽽庞⼤的社区,这就是它之所以能⻓久不衰的原因。Spring ⽀持⼴泛的应⽤场景,它可以让 Java 企业级的应⽤程序开发起来更简单。

⽤⼀句话概括 Spring:Spring 是包含了众多⼯具⽅法的 IoC 容器

容器是⽤来容纳某种物品的(基本)装置很好理解,那什么是IoC呢?

🎄什么是IoC呢?

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

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

🎈传统程序开发

假如,我们现在构建⼀辆“⻋”的程序,我们的实现思路是这样的:

构建⼀辆⻋(Car Class),然⽽⻋需要依赖⻋身(FrameWork Class),⽽⻋身需要依赖底盘(Bottom
Class),⽽底盘需要依赖轮胎(Tire Class)
在这里插入图片描述
在这里插入图片描述

代码实现如下:

Car class

package tradition;public class Car {private FrameWork frameWork;public Car () {//frameWork = new FrameWork();}public void init() {//启用车System.out.println("车启动,需要依赖车身");frameWork.init();}
}

FrameWork Class

package tradition;public class FrameWork {private Bottom bottom;public FrameWork() {bottom = new Bottom();}public void init() {//启用车身System.out.println("车身启动,需要依赖地盘");bottom.init();}
}

Bottom Class

package tradition;public class Bottom {private Tire tire;public Bottom() {//构造地盘。需要依赖轮胎tire = new Tire();}public void init() {System.out.println("底盘启动,需要依赖车轮");tire.init();}
}

Tire Class

package tradition;public class Tire {private int size = 20;public Tire() {//构造轮胎}public void init() {//启用轮胎System.out.println("轮胎尺寸为"+size);}
}

测试如下:

package tradition;public class App {public static void main(String[] args) {//测试Car car = new Car();car.init();}
}

测试结果:
在这里插入图片描述
这时候一辆简单的车也就构造好了

🎈传统程序开发的缺陷

但是以上程序中,轮胎的尺⼨的固定的,然⽽随着对的⻋的需求量越来越⼤,个性化需求也会越来越多,这时候我们就需要加⼯多种尺⼨的轮胎,那这个时候就要对上⾯的程序进⾏修改了,但是当我们对轮胎的尺寸进行重新构造时,我们发现我们需要对轮胎以上的底盘、车身、车都要重新构造,不然就会出错。代码实现如下:
Car class

package tradition;public class Car {private FrameWork frameWork;public Car (int size) {//frameWork = new FrameWork(size);}public void init() {//启用车System.out.println("车启动,需要依赖车身");frameWork.init();}
}

FrameWork Class

package tradition;public class FrameWork {private Bottom bottom;public FrameWork(int size) {bottom = new Bottom(size);}public void init() {//启用车身System.out.println("车身启动,需要依赖地盘");bottom.init();}
}

Bottom Class

package tradition;public class Bottom {private Tire tire;public Bottom(int size) {//构造地盘。需要依赖轮胎tire = new Tire(size);}public void init() {System.out.println("底盘启动,需要依赖车轮");tire.init();}
}

Tire Class

package tradition;public class Tire {private int size = 20;public Tire(int size) {//构造轮胎this.size = size;}public void init() {//启用轮胎System.out.println("轮胎尺寸为"+size);}
}

测试如下:

package tradition;public class App {public static void main(String[] args) {//测试Car car = new Car(30);car.init();}
}

测试结果如下:
在这里插入图片描述
上述写法当最底层代码改动之后,整个调⽤链上的所有代码都需要修改。牵一发而动全身,非常的不方便。

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

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

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

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

🎈控制反转式程序开发

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

package IoC;public class Car {private FrameWork frameWork;public Car (FrameWork frameWork) {this.frameWork = frameWork;}public void init() {//启用车System.out.println("车启动,需要依赖车身");frameWork.init();}
}

class FreameWork

package IoC;public class FrameWork {private Bottom bottom;public FrameWork(Bottom bottom) {this.bottom = bottom;}public void init() {//启用车身System.out.println("车身启动,需要依赖地盘");bottom.init();}
}

class Bottom

package IoC;public class Bottom {private Tire tire;public Bottom(Tire tire) {//构造地盘。需要依赖轮胎this.tire = tire;}public void init() {System.out.println("底盘启动,需要依赖车轮");tire.init();}
}

class Tire

package IoC;public class Tire {private int size = 20;public Tire(int size) {//构造轮胎this.size = size;}public void init() {//启用轮胎System.out.println("轮胎尺寸为"+size);}
}

class App

package IoC;public class App {public static void main(String[] args) {Tire tire = new Tire(30);Bottom bottom = new Bottom(tire);FrameWork frameWork = new FrameWork(bottom);Car car = new Car(frameWork);car.init();}
}

需要注意的是:

  • 在Spring中,我们是不需要像上述测试代码中这样创建对象,具体的方式,博主会在Spring创建与使用中进行介绍

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

🎈对⽐总结规律

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

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

在这里插入图片描述
我们发现了⼀个规:通⽤程序的实现代码,类的创建顺序是反的,传统代码是 Car 控制并创建了
Framework,Framework 创建并创建了 Bottom,依次往下,⽽改进之后的控制权发⽣的反转,不再是上级对象创建并控制下级对象了,⽽是下级对象把注⼊将当前对象中,下级的控制权不再由上级类控制了,这样即使下级类发⽣任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是 IoC 的实现思想

🍀理解 Spring IoC

回到我们的主题 Spring,本⽂刚开始咱们就讲:Spring 是包含了多个⼯具⽅法的 IoC 容器,这就是对Spring 最核⼼的总结。“集成多个⼯具⽅法”这事咱们以后慢慢再讲,那如何理解“Spring 是⼀个 IoC容器”这句话呢?

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

  • 将对象存⼊到容器;

  • 从容器中取出对象。

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

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

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

🎍DI 概念说明

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

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

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

比如我今天学习累了,准备去打一把游戏犒劳以下自己,这个打游戏的想法就是IoC。那具体打什么游戏呢?吃鸡、永劫无间、王者荣耀·······,这些具体要打的游戏就是DI

⭕总结

关于《【JavaEE进阶】 Spring核⼼与设计思想》就讲解到这儿,感谢大家的支持,欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下!

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

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

相关文章

适用于 Windows 的最佳(免费/付费)数据恢复软件

借助最佳数据恢复工具从 Windows PC 恢复丢失和删除的数据 您是否正在寻找一种巧妙的方法来从计算机中取消删除或恢复已删除的文件?如果是,那么这篇文章就是为您准备的!在本教程中,我们整理了一份全面的数据恢复软件列表&#xf…

Android 第三十九章 RatingBar

一、属性 android:isIndicator“false” 此评级栏是否为指示器(用户不可更改)。 默认false 可更改,true 不可更改android:numStars“6” 设置星星数量android:rating“1” 设置默认评级android:stepSize“2” 设置步长 二、示例 class Mai…

机器人学习目标

学习目标: 若干年后,我们都将化为尘土,无人铭记我们的存在。那么,何不趁现在,尽己所能,在这个世界上留下一些痕迹,让未来的时光里,仍有人能感知到我们的存在。 机器人协会每届每个阶…

在 Vue 3 项目中实现图片的在线预览(百度搜索暂未验证)

当使用 Vue 3 TypeScript Vite 完成图片在线预览时,你可以使用第三方库 vue-image-lightbox 来实现。以下是如何在 Vue 3 TypeScript Vite 项目中完成这个任务的示例: 首先,安装 vue-image-lightbox 库: npm install vue-ima…

外包干了4年,技术退步明显...

先说情况,大专毕业,18年通过校招进入湖南某软件公司,干了接近4年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&#xf…

Pip命令:Python包管理的利器

Pip是Python的一个强大的包管理工具,它可以帮助我们轻松地安装、升级和管理Python包。在这篇文章中,我将介绍Pip命令的基本用法和一些高级技巧。 安装Pip 在大多数Python发行版中,Pip都是默认安装的。如果你的系统中还没有安装Pip&#xff0c…

postgres pg_dump: fe_sendauth: no password supplied问题处理

postgres pg_dump: fe_sendauth: no password supplied问题处理 1、pg_dump: fe_sendauth: no password supplied问题处理(root 用户)2、解决方法2.1、创建 .pgpass文件2.2、chmod 600 ~/.pgpass 3、额外情况 1、pg_dump: fe_sendauth: no password supp…

codeforces每日两道思维题(第 二 天)

2 C. Challenging Cliffs 原题链接:Problem - 1537C - Codeforces rating : 1200 题目描述: 你是一名游戏设计师,想要创建一个障碍赛道。玩家将从左到右行走。你已经选择了 n 座山的高度,并希望安排它们,以便第一座…

SCAU:18037 20秒后的时间

18037 20秒后的时间 时间限制:1000MS 代码长度限制:10KB 提交次数:0 通过次数:0 题型: 编程题 语言: G;GCC Description 编写程序,输入三个整数变量hour(小时)、minute(分钟)、second(秒)…

优化网站性能,从容谈CDN加速的部署与运维

随着互联网的迅猛发展,网站的性能优化成为网站运维工作中不可或缺的一环。其中,CDN(Content Delivery Network)加速技术因其在全球范围内提供快速、可靠的内容分发而备受关注。本文将从一个网站运维的角度出发,深入探讨…

文件重命名:删除文件名中的空格,提高文件可读性和可管理性的方法

在计算机科学中,有效的文件管理对于提高工作效率和保持数据的一致性至关重要。工作中经常会遇到文件名中包含空格的情况,这不仅会使文件在某些情况下难以读取,而且可能导致管理上的困扰。在文件名中添加空格可能会使文件名变得模糊和不明确&a…

AIGC: 关于ChatGPT中基于API实现一个Client客户端

Java版的GPT的Client 可作为其他编程语言的参考注意: 下面包名中的 xxx 可以换成自己的 1 )核心代码结构设计 src main java com.xxx.gpt.client entity ChatCompletion.javaChatCompletionResponse.javaChatChoice.java… util Proxys.java… ChatApi.javaChatG…

我有才知识付费小程序免费搭建:轻松拥有知识付费平台

用户管理 提供会员特权和积分奖励,提高用户忠诚度和购买力。 用户通过在平台上进行消费、签到、参与活动等方式获取积分,用于兑换丰厚奖品或提升会员等级。增强用户的参与感与忠诚度,提高用户粘性,并刺激用户的购买力。 为用户打…

7z命令压缩文件夹,并忽略其中某些文件夹

-xr指令表示忽略 对于.vs这样的文件夹,需要用双引号括起来 类似的,可以使用通配符忽略文件 .\7z.exe a -t7z D:\Document\Code\apps.7z D:\Document\Code\apps -xr!".vs" -xr!bin -xr!obj

编码生成规则Long increment(K key, long delta)

前端不传数据&#xff0c;像一些 需要 从后台查出来的编码的生成规则&#xff1b; 采用方法为&#xff1a;Long increment(K key, long delta) redisTemplate.opsForValue()中的方法都定义在ValueOperations<K, V> 中&#xff0c;该接口中一共有17个方法&#xff1a; …

Arduino学习笔记2023年11月30日

目录 1 编程软件下载2 代码结构3 IO引脚控制3.1 引脚初始化3.2 引脚使用数字量输出数字量输入模拟量输出模拟量输入 4 串口串口初始化串口输出串口输入 5 外部中断6 函数6.1 映射区间函数6.2 延时函数 总结 1 编程软件下载 官网链接&#xff1a;https://www.arduino.cc/ 下载链…

SpringBoot 配置文件使用@ @取值

目录 一、背景 二、遇到的问题 三、解决办法 一、背景 &#xff08;1&#xff09;我在项目中引入了如下依赖&#xff0c;目的是开启SpringBoot为我们提供的监控(Actuator)功能。 <!-- 引入SpringBoot 监控功能 --> <dependency><groupId>org.springframew…

PWM控制器电路D9741,定时闩锁、短路保护电路,输出基准电压(2.5V) 采用SOP16封装形式

D9741是一块脉宽调制方三用于也收路像机和笔记本电的等设备上的直流转换器。在便携式的仪器设备上。 主要特点&#xff1a;● 高精度基准电路 ● 定时闩锁、短路保护电路 ● 低电压输入时误操作保护电路 ● 输出基准电…

Linux服务器部署XXL-JOB

参考文档及下载地址&#xff1a;分布式任务调度平台XXL-JOB 1 从git拉取XXL-JOB代码 我们的大部分变动&#xff0c;是发生在xxl-job-admin&#xff0c;最终将这个模块打包成jar包部署在linux服务器上。 2 执行数据库脚本 doc\db\tables_xxl_job.sql 3 修改pom文件&#xff0c…

golang常用库之-操作sqlite数据库

文章目录 一、sqlite使用sqlite3命令行工具创建数据库&#xff0c;查询数据 二、关于mattn/go-sqlite3三、mattn/go-sqlite3使用四、go 使用sqlite常见问题总结window下编译报错&#xff1a;Binary was compiled with CGO_ENABLED0, go-sqlite3 requirewindow下编译报错&#x…