Spring基础与核心概念

Spring 是什么?

我们通常所说的 Spring 指的是 Spring Framework(Spring 框架),它是⼀个开源框架,有着活跃而庞大的社区,这就是它之所以能长久不衰的原因。Spring 支持广泛的应⽤场景,它可以让 Java 企业级的应⽤程序开发起来更简单。
⽤⼀句话概括 Spring:Spring 是包含了众多工具方法的 IoC 容器。
那问题来了,什么是容器?什么是 IoC 容器?接下来我们⼀起来看。

什么是容器?

容器是⽤来容纳某种物品的(基本)装置。 ——来⾃:百度百科
我们想想,之前课程我们接触的容器有哪些?
List/Map -> 数据存储容器
Tomcat -> Web 容器
比如一个web,光有一个web的话是运行不起来的,你得需要把这个web放到toncat这个web容器上,才能运行起来

什么是 IoC?

Spring 也是⼀个容器,Spring 是什么容器呢?Spring 是⼀个 IoC 容器
什么是 IoC?
IoC = Inversion of Control 翻译成中⽂是“控制反转”的意思,也就是说 Spring 是⼀个“控制反转”的容器,由于这个“控制翻转”是英文直译过来的,有一些差别,实际上叫做控制(权)翻转
怎么理解这句话呢?
比如我们传统的java创建对象的方式是new一个新对象,这个对象的生命周期由我们程序员(当前代码)来控制的,因此我们就有了这个对象的控制权,什么是翻转呢?就是这个对象由被我们控制变成不被我们控制了,而是交给spring(也可以叫spring容器/IoC容器)来控制了,交给spring控制之后,我们不需要自己再new一个新对象了,只需要告诉spring我们要一个对象,它就会给我们一个
因此,控制权翻转可以理解为:对象的生命周期,不由程序员(或当前代码片段)来控制,而是由spring(也可以叫spring容器/IoC容器)来控制了

为什么要用IoC

IoC优点:可以实现解耦合(松耦合)

假如,我们现在构建⼀辆“⻋”的程序,我们的实现思路是这样的:
在这里插入图片描述
构建⼀辆⻋(Car Class),然⽽⻋需要依赖⻋身(FrameWork Class),⽽⻋身需要依赖底盘(BottomClass),⽽底盘需要依赖轮胎(Tire Class),最终程序的实现代码如下:

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

以上程序中,轮胎的尺⼨的固定的,然⽽随着对的⻋的需求量越来越⼤,个性化需求也会越来越多,这时候我们就需要加⼯多种尺⼨的轮胎,那这个时候就要对上⾯的程序进⾏修改了,修改后的代码如下所示:

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

从以上代码可以看出,以上程序的问题是:当最底层代码改动之后,整个调用链上的所有代码都需要修改
如何解决上述问题呢?
我们可以尝试不在每个类中自己创建下级类,如果自己创建下级类就会出现当下级类发⽣改变操作,自己也要跟着修改。
此时,我们只需要将原来由自己创建的下级类,改为传递的方式(也就是注入的方式),因为我们不需要在当前类中创建下级类了,所以下级类即使发生变化(创建或减少参数),当前类本身也无需修改任何代码,这样就完成了程序的解耦
PS:解耦指的是解决了代码的耦合性,耦合性也可以换⼀种叫法叫程序相关性。好的程序代码的耦合性(代码之间的相关性)是很低的,也就是代码之间要实现解耦。
这就好⽐我们打造⼀辆完整的汽车,如果所有的配件都是自己造,那么当客户需求发生改变的时候,比如轮胎的尺寸不再是原来的尺寸了,那我们要自己动⼿来改了,但如果我们是把轮胎外包出去,那么即使是轮胎的尺寸发⽣变变了,我们只需要向代理工厂下订单就行了,我们自身是不需要出⼒的。
基于以上思路,我们把调⽤汽⻋的程序示例改造⼀下,把创建⼦类的⽅式,改为注⼊传递的⽅式,具体实现代码如下

public class IocCarExample {public static void main(String[] args) {//以下四行是模拟spring ioc容器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;}public void run() {framework.init();}}static class Framework {private Bottom bottom;public Framework(Bottom bottom) {this.bottom = bottom;}public void init() {bottom.init();}}static class Bottom {private Tire tire;public Bottom(Tire tire) {this.tire = tire;}public void init() {tire.init();}}static class Tire {private int size;public Tire(int size) {this.size = size;}public void init() {System.out.println("轮胎:" + size);}}
}

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

在传统的代码中对象创建顺序是:Car -> Framework -> Bottom -> Tire
改进之后解耦的代码的对象创建顺序是:Tire -> Bottom -> Framework -> Car
在这里插入图片描述
我们发现了⼀个规律:通⽤程序的实现代码,类的创建顺序是反的,传统代码是 Car 控制并创建了Framework,Framework 创建并创建了 Bottom,依次往下,⽽改进之后的控制权发⽣的反转,不再是上级对象创建并控制下级对象了,⽽是下级对象把注⼊将当前对象中,下级的控制权不再由上级类控制了,这样即使下级类发⽣任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是 IoC 的实现思想。
既然 Spring 是⼀个 IoC(控制反转)容器,重点还在“容器”⼆字上,那么它就具备两个最基础的功能:
将对象存⼊到容器;
从容器中取出对象。
也就是说学 Spring 最核心的功能,就是学如何将对象存⼊到 Spring 中,再从 Spring 中获取对象的过程。IoC容器管理的资源的是对象,对象在ioc的叫法叫Bean
将对象存放到容器中的好处:将对象存储在 IoC 容器相当于将以后可能⽤的所有⼯具制作好都放到仓库中,需要的时候直接取就⾏了,⽤完再把它放回到仓库。⽽ new 对象的⽅式相当于,每次需要⼯具了,才现做,⽤完就扔掉了也不会保存,下次再⽤的时候还得重新做,这就是 IoC 容器和普通程序开发的区别。

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

DI概念说明

说到 IoC 不得不提的⼀个词就是“DI”,DI 是 Dependency Injection 的缩写,翻译成中⽂是“依赖注入”的意思。
所谓依赖注⼊,就是由 IoC 容器在运⾏期间,动态地将某种依赖关系注⼊到对象之中。所以,依赖注⼊(DI)和控制反转(IoC)是从不同的⻆度的描述的同⼀件事情,就是指通过引⼊ IoC 容器,利⽤依赖关系注⼊的⽅式,实现对象之间的解耦
IoC 是“目标”也是⼀种思想,而目标和思想只是⼀种指导原则,最终还是要有可行的落地方案,而 DI就属于具体的实现。
比如说我今天心情比较好,吃⼀顿好的犒劳犒劳自己,那么“吃⼀顿好的”是思想和目标(是 IoC),但最后我是吃海底捞还是杨国福?这就是具体的实现,就是 DI
怎么理解:动态地将某种依赖关系注⼊到对象之中
这句话呢?
看下图
比如我在运行car类的时候,需要用到Framework这个类,现在我运行car了,ioc容器就知道我依赖的是framework这个对象,于是就可以在运行时候动态的把容器里的framework对象给car类里的framework对象,这样用到framework对象的时候就不至于是空指针异常了
在这里插入图片描述

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

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

相关文章

大数据Doris(一):Doris概述篇

文章目录 Doris概述篇 一、前言 二、Doris简介

Vue封装全局SVG组件

1.SVG图标配置 1.安装插件 npm install vite-plugin-svg-icons -D 2.Vite.config.ts中配置 import { createSvgIconsPlugin } from vite-plugin-svg-icons import path from path export default () > {return {plugins: [createSvgIconsPlugin({// Specify the icon fo…

04. 人工智能核心基础 - 导论(3)

文章目录 人工智能和其他学科的关系为什么学习人工智能怎么学好人工智能?一些问题 Hi,你好。我是茶桁。 基于上一节课咱们的整体强度有点大,而且咱们马上也要进入高强度内容了,那么这一篇咱们就稍微水一篇吧。来聊聊天&#xff0…

FPGA 多路视频处理:图像缩放+视频拼接显示,HDMI采集,提供2套工程源码和技术支持

目录 1、前言版本更新说明免责声明 2、相关方案推荐FPGA图像缩放方案推荐FPGA视频拼接方案推荐 3、设计思路框架视频源选择IT6802解码芯片配置及采集动态彩条缓冲FIFO图像缩放模块详解设计框图代码框图2种插值算法的整合与选择 视频拼接算法图像缓存视频输出 4、vivado工程1&am…

【计算机网络】图解路由器(一)

本系列包含: 图解路由器(一)图解路由器(二) 图解路由器(一) 1、什么是路由器?2、什么是路由选择?3、什么是转发?4、路由器设备有哪些类型?5、根据…

【小笔记】fasttext文本分类问题分析

【学而不思则罔,思维不学则怠】 2023.9.28 关于fasttext的原理及实战文章很多,我也尝试在自己的任务中进行使用,是一个典型的短文本分类任务,对知识图谱抽取的实体进行校验,判断实体类别是否正确,我构建了…

高级时钟项目(2)Json文件解析学习---C语言版本

笔者来介绍一下json文件解析 1、背景介绍 笔者在获取天气数据的时候,是通过MCU的WIFI去获取,但是获取到的数据json数据,需要解析,C语言没那么解析库,所以就需要找一些开源的解析库。 笔者找到cjson这个适用于C语言…

【c语言】通讯录【动态版本:有排序和文件操作】

目录 一、通讯录定义 二、通讯录的实现 1、test.c中菜单的实现 2、通讯录的创建逻辑 3、初始化 4、检查容量和添加 5、查找 6、删除功能 7、修改功能 8、打印 9、查找并打印 10、qsort排序 11、摧毁 12、保存数据到文件 13、从文件中读数据 完整代码: 一、通讯录定…

【C++进阶(六)】STL大法--栈和队列深度剖析优先级队列适配器原理

💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:C从入门到精通⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习C   🔝🔝 栈和队列 1. 前言2. 栈和队列的接口函数熟悉3. …

基础算法--KMP字符串

KMP 算法是一个快速查找匹配串的算法,它的作用其实就是本题问题:如何快速在「原字符串」中找到「匹配字符串」。 在朴素解法中,不考虑剪枝的话复杂度是 O(m∗n) 的,而 KMP 算法的复杂度为 O(mn)。 KMP 之所以能够在O(mn) 复杂度内…

leetCode 213. 打家劫舍 II 动态规划 房间连成环怎么偷呢?

213. 打家劫舍 II - 力扣(LeetCode) 你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装…

如何定时备份使用Docker构建的MySQL容器中的数据库

👨🏻‍💻 热爱摄影的程序员 👨🏻‍🎨 喜欢编码的设计师 🧕🏻 擅长设计的剪辑师 🧑🏻‍🏫 一位高冷无情的编码爱好者 大家好,我是 DevO…

PIE:1979-2018年中国气温数据产品(空间分辨率为0.1º)

简介 中国气温数据产品包含1979-2018年期间中国的近地表气温数据(单位为摄氏度),时间分辨率为每日,空间分辨率为0.1。本产品集成了再分析数据(ERA5、CMFD)、遥感数据(MODIS)、原位数…

php eayswoole node axios crypto-js 实现大文件分片上传复盘

不啰嗦 直接上步骤 步骤1.开发环境配置 项目需要node.js 做前端支撑 官网下载地址: http://nodejs.cn/download/ 根据自己需要下载对应的版本,我下载的是windows系统64位的版本。 包下载好后 进行安装,安装步骤在此省略... 测试是否安装成功 …

蓝海彤翔亮相2023新疆网络文化节重点项目“新疆动漫节”

9月22日上午,2023新疆网络文化节重点项目“新疆动漫节”(以下简称“2023新疆动漫节”)在克拉玛依科学技术馆隆重开幕,蓝海彤翔作为国内知名的文化科技产业集团应邀参与此次活动,并在美好新疆e起向未来动漫展映区设置展…

C#生成自定义海报

安装包 SixLabors.ImageSharp.Drawing 2.0 需要的字体:宋体和微软雅黑 商用的需要授权如果商业使用可以使用方正书宋、方正黑体,他们可以免费商用 方正官网 代码 using SixLabors.Fonts; using SixLabors.ImageSharp; using SixLabors.ImageSharp.Draw…

使用SPY++查看窗口信息去排查客户端UI软件问题

目录 1、使用SPY查看窗口的信息 2、使用SPY查看某些软件UI窗口用什么UI组件实现的 2.1、查看海康视频监控客户端安装包程序 2.2、查看华为协同办公软件WeLink 2.3、查看字节协同办公软件飞书 2.4、查看最新版本的Chrome浏览器 2.5、查看小鱼易连视频会议客户端软件 2.6…

CIP或者EtherNET/IP中的PATH是什么含义?

目录 SegmentPATH举例 最近在学习EtherNET/IP,PATH不太明白,翻了翻规范,在这里记个笔记。下面的叙述可能是中英混合,有一些是规范中的原文我直接搬过来的。我翻译的不准确。 Segment PATH是CIP Segment中的一个分类。要了解PATH…

Dev C++安装与运行

参考: https://blog.csdn.net/Keven_11/article/details/126388791 https://www.cnblogs.com/-Wallace-/p/cpp-stl.html 2021年真题要求 2022年真题要求 河南省的考试环境 IDE环境 Dev C 安装 下载 安装 点击OK,选择我接受 修改安装路径为D盘d:\Program Fi…

MQTT协议是什么?快速了解MQTT协议在物联网中的应用

随着工业互联网的迅猛发展,工业设备数据采集和实时监控成为制造业提高生产效率和质量的重要手段。在物联网应用中,通信技术包括Wi-Fi、RFID、NFC、RS232、RS485、USB等,其中在物联网技术框架体系中所使用到的通讯协议主要有:AMQP、…