【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.hqwc.cn/news/62224.html

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

相关文章

R语言安装包Seurat

环境Ubuntu22,R4.1 also installing the dependencies ‘curl’, ‘openssl’, ‘httr’, ‘plotly’ R包安装的时候报了这个错误ERROR: dependencies httr, plotly are not available for package Seurat 解决方法,退出R,在terminal中键入…

突破笔试:力扣129. 求根节点到叶节点数字之和

1. 题目链接:129. 求根节点到叶节点数字之和 给你一个二叉树的根节点 root ,树中每个节点都存放有一个 0 到 9 之间的数字。每条从根节点到叶节点的路径都代表一个数字:例如,从根节点到叶节点的路径 1 -> 2 -> 3 表示数字 …

QT中的PRO文件怎么进行相关的信息的注释?

小白学开发之QT下的PRO文件怎么进行注释,以及Pro文件的作用 Hello大家好,这里是程序员小白学开发,我是一个刚入门QT的初学者,晕乎晕乎的!希望能够随时随地将自己所学的知识分享给大家,带着大学从零基础开始…

MySQL数据库-基础篇

基础篇 一、SQL 分类 DDL-数据库操作 查询 创建表 数据类型 数值类型 字符串类型 日期类型 添加 修改 删除字段 修改表名 删除表 小结 DML-数据增删改 添加数据 修改数据 删除数据 小结 DQL-数据查询数据 基本查询 条件查询 聚合函数 分组查询 排序查询 分页查…

现在国家正规相亲平台有哪些?盘点五款安全值得使用的相亲软件

随着互联网的普及,越来越多的人选择通过相亲软件寻找自己的另一半。但是,在众多相亲软件中靠谱的相亲软件有哪些呢,该如何选择?本文将盘点几款安全靠谱的相亲软件,可以了解看看哪个适合你。 第一款:一伴婚…

红帽停止公开Linux操作系统(RHEL)源代码,甲骨文等企业成立协会

根据报道,红帽(Red Hat)在8月11日宣布停止公开企业级Linux操作系统(RHEL)的源代码后,甲骨文、SUSE和CIQ昨日联合发布了一份声明。声明宣布成立了Open Enterprise Linux Association(OpenELA&…

评述6种室内定位技术的底层原理及未来展望

从古至今,人类始终关心一个颇具哲学意味的问题——“我在哪里”。从千年前的人类在夜空下遥望星河,到依靠经验和模糊的观测绘制的初具现代化意味的地图,再到近现代人类在计算机技术、无线通信技术甚至空间技术的帮助下,不断探索更…

JVM入门到精通

一、JVM概念 1.1、什么是JVM Java Virtual Machine:Java虚拟机,用来保证Java语言跨平台 Java虚拟机可以看做是一台抽象的计算机,如同真实的计算机那样,它有自己的指令集以及各种运行时内存区域 Java虚拟机与Java语言并没有必然…

【办公自动化】使用Python一键提取PDF中的表格到Excel

🤵‍♂️ 个人主页:艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞&#x1f4…

毅哥铡特:修改后的Bellmanford最短路径路由动画演示

修改背景:毅哥铡特自带的《routing_bellmanford.cpp》,按路由跳数进行更新路由表,但是,卫星互联网的卫星路由器节点,可能需要考虑传播传输时延,对应的,可能需要按照两个网络节点的距离来更新路由…

【网络】高级IO

目录 一、五种IO模型 1、阻塞IO 2、非阻塞IO 3、信号驱动 4、IO多路转接 5、异步IO 6、总结 二、高级IO重要概念 1、同步通信与异步通信 2、阻塞 vs 非阻塞 三、非阻塞IO 1、fcntl 2、实现函数SetNoBlock 四、IO多路转接select 1、select 1.1、参数解释 1.2、…

附件展示 点击下载

效果图 实现代码 <el-table-column prop"attachment" label"合同附件" width"250" show-overflow-tooltip><template slot-scope"scope"><div v-if"scope.row.cceedcAppendixInfoList &&scope.row.ccee…