【Spring】-Spring的IoC和DI

作者:学Java的冬瓜
博客主页:☀冬瓜的主页🌙
专栏:【Framework】
主要内容:什么是spring?IoC容器是什么?如何使代码解耦合?IoC的核心原理,IoC的优点。依赖注入/对象装配/DI。

在这里插入图片描述

在这里插入图片描述

文章目录

    • 一、什么是Spring?
      • 1)什么是IoC容器?
        • 1> 理解
        • 2> 法一,传递(存在依赖关系传对象)
        • 3> 法二,使用Spring
          • Spring IoC 核心操作:
          • Spring IoC 优点:
      • 2)什么是DI?

一、什么是Spring?

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

1)什么是IoC容器?

1> 理解

IoC 全称 Inversion of Control,翻译为控制反转。因此IoC容器就是控制反转的容器。那啥是 控制反转?Spring框架管理Bean的创建工作。即由用户管理Bean变为框架管理Bean

① 举个例子:接下来我们举个例子,并使用代码来感受啥是个IoC(控制反转),有什么好处:
比如建造一个房子,粗略的看,首先需要打地基,然后砌砖,最后挂房梁瓦片等。如果用代码实现这样一个粗略的过程,看下面代码:

//测试类
public class Test {public static void main(String[] args) {House house = new House();house.init();}
}
//房
public class House {public void init(){// 创建房子 依赖于挂房梁等操作Beam beam = new Beam();beam.init();System.out.println("House: House create");}
}
//房梁
public class Beam {private String material;//(杉木)public void init(){// 挂房梁等 依赖于 砌好砖Brick brick = new Brick();brick.init();System.out.println("Bean: 房梁木用 " + this.material);}
}
//砖
public class Brick {private String redBrick;//红砖public void init(){// 砌砖 依赖于 已经打好地基Foundation foundation = new Foundation();foundation.init();System.out.println("Brick: 砌砖用 " + this.redBrick);}
}
//地基
public class Foundation {private String rebar;//钢筋private String cement;//水泥public void init(){System.out.println("Foundation: 打地基用 " + this.rebar +" "+ this.cement);}
}

上述代码运行结果如下:
在这里插入图片描述

② 理解代码:上面的代码中,测试类中的main方法运行后,会创建一个空House对象,再进行House对象的初始化;在House对象初始化时,会创建一个空的Beam对象,然后进行beam对象的初始化(house依赖于beam,房子依赖于房梁);beam初始化时,会创建Brick对象,再进行brick对象的初始化(beam依赖于brick,房梁依赖于砌好砖);brick对象初始化时,会创建Foundation对象,并进行foundation对象的初始化。
简单来说,要想建房子,得先挂好房梁,要想挂房梁,得先砌好砖,要想砌砖,得先打好地基,这就是一个逐层调用进行初始化的过程,最终建好一个房子。但是这样操作会引入一个很致命的问题:代码耦合度非常高!

③ 问题:这样互相依赖的过程,如果底层的类发生改变,上层的类得相应改变。在上面代码中,我使用钢筋水泥打地基,用红砖来砌砖,用杉木来做房梁木,在每个类的调用init方法时将所需参数传进去,进行材料的初始化(我这里没弄,所以都是null)。那么理解到这里我们可以想一个问题,如果我不再使用红砖来砌砖,而是使用水泥砖了,或者我需要制定特定尺寸的砖,那么Brick类的属性就需要修改调整。这样在上层调用中(beam)也需要修改,在Beam类的init方法中,创建了Brick类,并使用brick.init(参数)这个方法进行砌砖的初始化,那么这里也是需要修改的,如果上层还有给brick传参的方法,那也还需要改,所以这样操作,代码耦合度会非常高。

④ IoC和Spring:怎么才能降低耦合,减少修改的成本?因为上述代码出现高耦合的原因:在当前类中的方法中,创建当前类所依赖的类的对象并逐层调用初始化对象,或者上层的代码给底层的类的属性传参数。
法一:当存在依赖关系时,在当前类的方法中不再自己创建和销毁所依赖的对象,而是让调用者传一个依赖对象给当前类(当前类需要一个成员变量是它所依赖的类),如果这个类还存在其他属性,也由调用者提供参数(这样就可保证,在我需要修改某一个类的成员或者类型时,其他类不需要做修改,即实现解耦合)。
法二:那如果我不让它逐层调用,而是统一交给一个工具去创建对象并初始化并管理对象呢?这就是控制反转,Spring就是管理对象的这样一个容器。

⑤ Spring:在管理方面,Spring是一个 IoC容器,它可以管理对象,包括创建销毁对象等。在操作方面,又因为是个 IoC容器,因此可以把对象存进Spring或者从Spring中获取对象。

2> 法一,传递(存在依赖关系传对象)

//测试类
package demo2;
public class Test {//测试传对象 解耦合代码public static void main(String[] args) {Foundation foundation = new Foundation("xx号钢筋", "xx号水泥");Brick brick = new Brick(foundation, "xx号红砖");Beam beam = new Beam(brick, "杉木");House house = new House(beam);house.init();}
}//House类
package demo2;
public class House {private Beam beam;public House(Beam beam){this.beam = beam;}public void init(){// 创建房子 依赖于挂房梁等操作beam.init();System.out.println("house: 房子建成");}
}//Beam类
package demo2;
public class Beam {private Brick brick;private String material;public Beam(Brick brick, String material){this.brick = brick;this.material = material;}public void init(){// 挂房梁等 依赖于 砌好砖brick.init();System.out.println("Bean: 房梁木用 " + this.material);}
}//Brick类
package demo2;
public class Brick {private Foundation foundation;private String redBrick;//红砖public Brick(Foundation foundation, String redBrick){// 砌砖 依赖于 已经打好地基this.foundation = foundation;this.redBrick = redBrick;//新增}public void init(){this.foundation.init();System.out.println("Brick: 砌砖用 " + this.redBrick);}
}//Foundation类
package demo2;
public class Foundation {private String rebar;//钢筋private String cement;//水泥public Foundation(String rebar, String cement){this.rebar = rebar;this.cement = cement;}public void init(){System.out.println("Foundation: 打地基用 " + this.rebar +" "+ this.cement);}
}

运行结果:
在这里插入图片描述

3> 法二,使用Spring

具体操作,看后面的博客

Spring IoC 核心操作:

存对象 取对象

Spring IoC 优点:

解耦合
使用方便(不再需要手动创建对象)
更加高效(默认情况,使用相同类只需要创建一个对象)

2)什么是DI?

IoC,(Inversion of Control 控制反转)是一种设计原则,指的是将对象的创建和依赖关系交给容器来完成而不是由对象自己管理依赖对象。
DI,(Dependency Injection 依赖注入),是IoC的一种具体的实现方式,它是通过将依赖对象注入到对象中来实现对象之间的解耦。
简而言之,IoC是一种思想,而DI是IoC的一种具体实现方式

补充1:实现IoC除了DI之外,还需要控制反转容器(在Spring中就是Spring容器)和配置信息(xml文件,描述对象和依赖关系的元数据)。

补充2:① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩(在这里列出这种序号,需要的自取)。

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

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

相关文章

【C++基础(九)】C++内存管理--new一个对象出来

💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:C从入门到精通⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习C   🔝🔝 C内存管理 1. 前言2. new2.1 new的使用方法2.2 …

MIT 6.830数据库系统 -- lab six

MIT 6.830数据库系统 -- lab six 项目拉取引言steal/no-force策略redo log与undo log日志格式和检查点 开始回滚练习1:LogFile.rollback() 恢复练习2:LogFile.recover() 测试结果疑问点分析 项目拉取 原项目使用ant进行项目构建,我已经更改为…

Nodejs安装及环境变量配置(修改全局安装依赖工具包和缓存文件夹及npm镜像源)

本机环境:win11家庭中文版 一、官网下载 二、安装 三、查看nodejs及npm版本号 1、查看node版本号 node -v 2、查看NPM版本号(安装nodejs时已自动安装npm) npm -v 四、配置npm全局下载工具包和缓存目录 1、查看安装目录 在本目录下创建no…

【学习日记】【FreeRTOS】手动任务切换详解

前言 本文是关于 FreeRTOS 中实现两个任务轮流切换并执行的代码详解。目前不支持优先级,仅实现两个任务轮流切换。 一、任务的自传 任务从生到死的过程究竟是怎么样的呢?(其实也没死),这个问题一直困扰着我&#xf…

【前端 | CSS】滚动到底部加载,滚动监听、懒加载

背景 在日常开发过程中,我们会遇到图片懒加载的功能,基本原理是,滚动条滚动到底部后再次获取数据进行渲染。 那怎么判断滚动条是否滚动到底部呢?滚动条滚动到底部触发时间的时机和方法又该怎样定义? 针对以上问题我…

关于技术转管理角色的认知

软件质量保障:所寫即所思|一个阿里质量人对测试的所感所悟。 程序员发展的岔路口 技术人做了几年专业工作之后,会来到一个重要的“分岔路口”,一边是专业的技术路线,一边是技术团队的管理路线。不少人就开始犯难&…

redis 数据结构(一)

Redis 为什么那么快 redis是一种内存数据库,所有的操作都是在内存中进行的,还有一种重要原因是:它的数据结构的设计对数据进行增删查改操作很高效。 redis的数据结构是什么 redis数据结构是对redis键值对值的数据类型的底层的实现&#xff0c…

网站SSL安全证书是什么及其重要性

网站SSL安全证书具体来说是一个数字文件,是由受信任的数字证书颁发机构(CA机构)进行审核颁发的,其中包含CA发布的信息,该信息表明该网站已使用加密连接进行了安全保护。 网站SSL安全证书也被称为SSL证书、https证书和…

CosmosAI欧盟数字超算新时代战略合作签约仪式在伦敦举行

据英国权威媒体获悉,由分布式超算网络服务商CosmosAI主办的欧盟数字超算新时代战略合作签约仪式将于8月14日英国伦敦历史悠久的莱福士OWO酒店隆重举办,该酒店曾作为爱德华七世国王加冕仪式以及丘吉尔二战办公室享誉盛名。 本次活动CosmosAI基金会联合创…

护网专题简单介绍

护网专题简单介绍 一、护网红蓝队介绍1.1、网络安全大事件1.2、护网行动由来1.3、护网行动中的角色二、红队介绍2.1、红队所需技能2.2、红队攻击流程 三、蓝队介绍3.1、蓝队所需技能3.2、蓝队防守四阶段3.3、蓝队前期准备 四、常见安全厂商介绍4.1、常见安全厂商 五、常见安全产…

【vue3】基础知识点-pinia

学习vue3,都会从基础知识点学起。了解setup函数,ref,recative,watch、computed、pinia等如何使用 今天说vue3组合式api,pinia 戳这里,跳转pinia中文文档 官网的基础示例中提供了三种写法 1、选择式api&a…

树莓派命令行运行调用音频文件的函数,不报错,没有声音解决办法

树莓派接上音频首先需要切换音频不是HDMI,然后可以双击运行wav文件可以播放,但是: 命令行直接运行wav文件报错: Playing WAVE twzc.wav : Signed 16 bit Little Endian, Rate 16000 Hz, Mono命令行运行main方法也是无法播放&am…

Zebec Protocol 将进军尼泊尔市场,通过 Zebec Card 推动地区金融平等

流支付正在成为一种全新的支付形态,Zebec Protocol 作为流支付的主要推崇者,正在积极的推动该支付方案向更广泛的应用场景拓展。目前,Zebec Protocol 成功的将流支付应用在薪酬支付领域,并通过收购 WageLink 将其纳入旗下&#xf…

消息中间件 —— 初识Kafka

文章目录 1、Kafka简介1.1、消息队列1.1.1、为什么要有消息队列?1.1.2、消息队列1.1.3、消息队列的分类1.1.4、p2p 和 发布订阅MQ的比较1.1.5、消息系统的使用场景1.1.6、常见的消息系统 1.2、Kafka简介1.2.1、简介1.2.2、设计目标1.2.3、kafka核心的概念 2、Kafka的…

git 报错 protocol ‘https‘ is not supported解决

报错原因:选择不了其他分支代码,甚至都看不到其他分支,我这边解决了两次报错,情况如下: 第一种报错: idea中刷新分支报错如下: Fetch Failed protocol https is not supported 话不多说&#…

有没有推荐的golang的练手项目?

前言 下面是github上的golang项目,适合练手,可以自己选择一些项目去练习,整理不易,希望能多多点赞收藏一下!废话少说,我们直接进入正题>>> 先推荐几个教程性质的项目(用于新手学习、巩…

Qt在mac安装

先在app store下载好Xcode 打开Xcode 随便建个文件 给它取个名字 找个地方放 提醒没建立git link,不用理他 打开终端, 输入/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 开始安装啦 继续在终端…

【Uni-App】uview 开发多端应用,密码显示隐藏功能不生效问题

出现的问题: 使用uview组件u-input框密码绑定时会出现右侧密码显隐图标不显示的问题 思路: 1.看了下uview源码,发现这有一段注释,我们需要把源码修改一下,问题出在这里 这行代码修改为 :password"password || …

山东布谷科技直播系统源码热点分析:不同芯片实现高质量编码与渲染视频的GPU加速功能

在现代科技的迅猛发展下,直播系统源码平台被开发搭建出来,为人们的生活方式带来了很大的改变,直播系统源码平台的好友、短视频、直播、社区等功能让很多人越来越热衷于去在平台上刷视频、看直播、分享生活。用户的喜爱也督促了直播系统源码平…

【数据结构与算法】十大经典排序算法-快速排序

🌟个人博客:www.hellocode.top 🏰Java知识导航:Java-Navigate 🔥CSDN:HelloCode. 🌞知乎:HelloCode 🌴掘金:HelloCode ⚡如有问题,欢迎指正&#…