Spring IoCDI(1)—入门

news2024/11/18 5:52:55

目录

一、IoC & DI入门

1、Spring是什么

(1)什么是容器?

(2)什么是IoC?

二、IoC介绍

1、传统程序开发

2、解决方案

3、IoC程序开发

4、IoC优势

三、DI介绍


        通过前面的学习,我们知道Spring是一个开源框架,它能让我们的开发更简单,它支持广泛的应用场景,有着活跃而庞大的社区,这也是Spring长久不衰的原因。但是这个概念还是比较抽象的,我们用一句更具体的话来概括Spring:Spring是包含了众多工具方法的IoC容器

一、IoC & DI入门

1、Spring是什么

(1)什么是容器?

        容器是用来容纳某种物品的(基本)装置。——来自:百度百科。生活中的水杯、垃圾桶、冰箱等等这些都是容器,之前接触过的容器:List/Map->数据存储容器、Tomcat->Web容器。

(2)什么是IoC?

        IoC是Spring的核心思想,也是常见的面试题,那么什么是IoC呢?其实IoC在前面的代码练习已经使用过了,比如在类上面添加 @RestController 和 @Controller 注解,就是把这个对象交给Spring管理,Spring框架启动时,就会加载该类。——把对象交给Spring管理,这就是IoC思想

        IoCInversion of Control(控制反转),也就是说Spring是一个“控制反转”的容器

什么是控制反转呢?就是控制权反转。什么控制权发生了反转?获得依赖对象的过程被反转了也就是说,当需要某个对象时,传统开发模式需要自己通过 new 创建对象,现在不需要再进行创建了,把创建对象的任务交给容器,程序中只需要依赖注入(Dependency Injection,简称DI)就可以了。这个容器称为:IoC容器。Spring是一个IoC容器,所以有时也称为Spring容器

        控制反转是一种思想,在生活中也处处体现比如自动驾驶,传统驾驶方式,车辆的横向和纵向驾驶控制权由驾驶员来控制,现在交给了驾驶自动化系统来控制,这也是控制反转思想在生活中的实现;还有招聘,企业的员工招聘、入职、解雇等控制权,由老板转交给HR(人力资源)来处理;还有外包等等


二、IoC介绍

下面通过案例来介绍什么是IoC,现在需求:造一辆车

1、传统程序开发

        我们是实现思路是这样的:先设计轮子(Tire),然后根据轮子的大小设计底盘(;),接着根据底盘设计车身(FrameWork),最后根据车身设计好整个汽车(Car)。这里就出现了一个 “依赖” 关系:汽车依赖车身,车身依赖底盘,底盘依赖轮子。如图:

        代码实现如下:

public class Main {
    public static void main(String[] args) {
        Car car = new Car();
        car.run();
    }
}

public class Car {
    private FrameWork frameWork;
    public Car() {
        frameWork = new FrameWork(17);
        System.out.println("frameWork init....");
    }
    public void run() {
        System.out.println("Car run...");
    }
}

public class FrameWork {
    private Bottom bottom;
    public FrameWork(int size) {
        bottom = new Bottom(size);
        System.out.println("Bottom init...");
    }
}


public class Bottom {
    private Tire tire;
    public Bottom(int size) {
        tire = new Tire(size);
        System.out.println("Tire init....");
    }
}

public class Tire {
    private int size;
    public Tire(int size) {
        this.size = size;
    }
}

        程序跑起来,控制台结果如图:

        

        但是现在又有需求了,要修改轮胎的颜色,那就要多添加一个属性,那么传参的时候,Car类、FrameWork类、Bottom类、Tire类的构造函数都要多添加一个元素,传参也要多传一个颜色属性。那么这样的话,耦合就很高而这也只是简单的给轮胎添加一个属性,随着项目需求的增加,项目也会越来越复杂,现在的代码可维护性也很差,就不太合适了。所以,要进行改进

2、解决方案

        上面的程序中,我们是根据轮胎的尺寸设计底盘的,轮胎的尺寸已改,底盘的设计也就得改,而车身依赖底盘,就会导致一连串的问题,几乎整个设计都得改。

        现在尝试换一种思路,我们先设计汽车的大概样子,然后根据汽车的样子来设计车身,根据车身来设计底盘,最后根据底盘设计轮胎。这时候,依赖关系就反转过来了:轮胎依赖底盘,底盘依赖车身,车身依赖汽车

这就类似我们造一辆完整的汽车,如果所有的配件都是自己造,那么客户需求发生改变的时候,比如轮胎尺寸不再是原来的尺寸了,那我们就要自己手动来改了,但如果把轮胎外包出去,那么即使轮胎的尺寸发生改变,那么我们只需要向代理工厂下订单就行了,我们自身是不需要出力的

        如何实现呢?我们可以尝试不在每个类中创建下级类,如果自己创建下级类就会出现当下级类发生改变操作,自己也要跟着修改。此时我们只需要将原来有自己创建的下级类,改为注入的方式,因为我们不需要在当前类中创建下级类了,所以下级类即使发生变化(创建或减少参数),当前类本身也无需修改任何代码,这样就完成了程序的解耦

3、IoC程序开发

        基于以上思路,我们把调用汽车的程序示例改造一下,把创建子类的方式,改为注入传递的方式。具体代码如下:

public class Main {
    public static void main(String[] args) {
        Tire tire = new Tire(17);
        Bottom bottom = new Bottom(tire);
        FrameWork frameWork = new FrameWork(bottom);
        Car car = new Car(frameWork);
        car.run();
    }
}

public class Car {
    private FrameWork frameWork;
    public Car(FrameWork frameWork) {
        this.frameWork = frameWork;
        System.out.println("frameWork init....");
    }
    public void run() {
        System.out.println("Car run...");
    }
}

public class FrameWork {
    private Bottom bottom;
    public FrameWork(Bottom bottom) {
        this.bottom = bottom;
        System.out.println("Bottom init...");
    }
}

public class Bottom {
    private Tire tire;
    public Bottom(Tire tire) {
        this.tire = tire;
        System.out.println("Tire init....");
    }
}

public class Tire {
    private int size;
    public Tire(int size) {
        this.size = size;
        System.out.println("size:" + size);
    }
}

        这样,如果轮胎需要修改尺寸,或者添加一个属性,只需要修改Tire类就好了,其他类不需要修改,达到了解耦的效果。

4、IoC优势

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

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

        我们发现了一个规律,通过程序的实现代码,类的创建顺序是反的,传统代码是Car控制并创建了Framework,Framework的创建也会继续创建Bottom,依次往下递推而改进后的控制权发生了反转,不再是使用方创建对象并控制依赖对象了,而是把依赖对象注入到当前对象中,依赖对象的控制权不再由当前类控制。这样的话,即使依赖类发生任何改变,当前类都是不受影响的,这就是典型的控制反转,也是IoC的实现思想。

        而控制反转容器也就是IoC容器,如图:

        这部分代码,也是IoC容器做的工作。

        从上面可以看出,IoC具有以下优点:资源不由使用资源的双方管理,而由使用资源的第三方管理,这可以带来很多好处。第一,资源集中管理,实现资源的可配置和易管理第二,降低使用资源双方的依赖程度,也就是我们说的耦合度

        资源集中管理IoC容器会帮我们管理一些资源(对象等),我们需要使用时,只需要从IoC容器中去取就可以了

        解耦合我们在创建实例的时候不需要了解其中的细节,降低了使用资源双方的依赖程度,也就是耦合度

        而Spring就是一种IoC容器,帮助我们来做了这些资源管理。


三、DI介绍

        DIDependency Injection(依赖注入)容器在运行期间,动态的为应用程序提供运行时所依赖的资源,称为依赖注入

        程序运行时,需要某个资源,此时容器就为其提供这个资源。从这点来看,依赖注入(DI)和 控制反转(IoC)是从不同的角度描述同一件事,就是指通过引入IoC容器,利用依赖关系注入的方式,实现对象之间的解耦

        上面改进后的代码,就是通过构造函数,把依赖对象注入到需要使用的对象中。如图:

        IoC是一种思想,也是 “目标”,而思想只是一种指导原则,最终还是要有可行的落地方案,而DI就属于具体的实现。所以也可以说,DI是IoC的一种实现

        就像我今天心情比较好,想吃顿大餐奖励自己,那么 “吃大餐” 就是思想和目标(是IoC),但最后我是吃什么大餐,肯德基还是海底捞等等,这个就是具体实现,就是DI。


都看到这了,点个赞再走吧,谢谢谢谢谢

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

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

相关文章

【项目实战】使用Yolov8 + tesseract 实现身份证信息解析(OCR) + 输入可为图片或者pdf + 完整代码 + 整体方案 + 全网首发

本项目可用于实验,毕业设计参考等。整体效果如下所示: 说明:图片来源于网络,如有侵权,请联系作者删除。 目录 一 数据集制作

【论文笔记】KAN: Kolmogorov-Arnold Networks 全新神经网络架构KAN,MLP的潜在替代者

KAN: Kolmogorov-Arnold Networks code:https://github.com/KindXiaoming/pykan Background ​ 多层感知机(MLP)是机器学习中拟合非线性函数的默认模型,在众多深度学习模型中被广泛的应用。但MLP存在很多明显的缺点:…

电机控制系列模块解析(19)—— 反电势观测器

随着现代工业自动化技术的飞速发展,交流电机作为关键的动力装置,其控制精度与效率日益受到重视。其中,无位置传感器控制技术由于其成本低、可靠性高、系统简洁等优点,逐渐成为研究热点。本文将对交流电机反电势观测器这一关键技术…

DevExpress Reporting 根据某个字段,合并单元格

1、根据字段值合并列(设置为Merge、Value) 2、根据字段Tag值合并列(设置为Merge、Tag,并且手动绑定字段Tag值)

uniapp + vue3 设置 axios proxy 代理,并重写路径

uniapp vue2 设置代理如下: 已生成的项目架构里面找到manifest.json文件,通过源码视图的方式打开文件,在文件中添加一下代码即可完成代理: "h5": {"devServer": {"disableHostCheck": true, //禁…

搜维尔科技:OptiTrack是基于LED墙虚拟制作舞台的最佳选择

OptiTrack因其绝对精度、易用性、可靠性以及与现场工具的完美集成而被选中&#xff0c;仍然是全球首屈一指的基于 LED 墙的虚拟制作舞台的选择。 当今虚拟制作阶段的低延迟、超精确摄像机跟踪标准 /- 0.2 毫米 位置精度1 < 10 毫秒 系统延迟 /- 0.1 度 旋转精度2 电影…

Windows电脑搭建HarmonyOS NEXTDeveloper Preview2环境详解

Windows电脑搭建HarmonyOS NEXTDeveloper Preview2环境详解&#xff1a; HarmonyOS NEXT Preview系列教程基于Api11讲解-IT营大地老师 1 、电脑要求以及注意事项 操作系统 &#xff1a; Windows10 64 位、 Windows11 64 位 内存 &#xff1a; 8GB 及以上&#xff0c;推荐 16G…

基于springboot实现公交线路查询系统项目【项目源码+论文说明】计算机毕业设计

基于SpringBoot实现公交线路查询系统演示 摘要 社会发展日新月异&#xff0c;用计算机应用实现数据管理功能已经算是很完善的了&#xff0c;但是随着移动互联网的到来&#xff0c;处理信息不再受制于地理位置的限制&#xff0c;处理信息及时高效&#xff0c;备受人们的喜爱。本…

解决在C#中方向键对控件焦点的控制

不要犹豫直接把下面这个程序复制进去就好了&#xff0c;不用担心0个引用&#xff0c;哈哈&#xff0c;可以的 public partial class MainForm : Form {public MainForm(){InitializeComponent();}protected override bool ProcessDialogKey(Keys keyData){// 检查是否是方向键…

RoNID:通过生成可靠标签与聚类友好型表征来实现新意图的发现

论文地址&#xff1a;https://arxiv.org/abs/2404.08977 原文地址&#xff1a;intents-are-not-going-away-ronid-is-a-new-intent-discovery-framework 2024 年 4 月 26 日 Robust New Intent Discovery&#xff08;RoNID&#xff09;框架致力于在开放域场景中识别已知意图并合…

Windows录屏怎么录?3个方法教会你

在Windows操作系统中&#xff0c;Windows录屏功能已经成为了许多用户日常工作与生活的必备工具。无论是教学演示、游戏直播&#xff0c;还是会议记录、视频教程制作&#xff0c;Windows录屏软件都能帮助我们轻松捕捉屏幕上的精彩瞬间。 本文将为您带来3种Windows录屏的方法&am…

1553B总线接口仿真卡,1553B IP核,适用于航空机载,飞机综合航电等领域

1553B总线接口卡可作为通讯或仿真测试板卡使用&#xff0c;支持USB&#xff0c;PCI&#xff0c;PXI&#xff0c;CPCI&#xff0c;以太网&#xff0c;RS422&#xff0c;RS485等计算机总线平台&#xff0c;单功能&#xff08;1个BC、0-31个RT和1个BM&#xff0c;当前仅可单工作模…

大模型相关技术-初识RAG

这个时候如果想对用户输入做一些过滤、对某种回答有了固定的答案怎么办呢&#xff1f;java程序员肯定就会想到写个filter或者intercepter&#xff0c;RAG就是在做类似的事情&#xff0c;只不过流程更加复杂。 RAG是什么 检索增强生成&#xff08;RAG&#xff09;是对大型语言…

c++:优先级队列(priority queue)使用及底层详解,附带仿函数初步使用

文章目录 优先级队列的使用大堆小堆**注意** 优先级队列的模拟实现pushpopsizeemptytop 仿函数仿函数是什么pushpop 仿函数结合优先级队列的优势 优先级队列的使用 优先级队列本质是就是完全二叉树,是个堆.我们可以用优先级队列来取出一段序列中的前N个最大值. priority_queue…

【k8s多集群管理平台开发实践】十二、开发总结及注意事项【完结】

文章目录 简介总结前面11章节所实现的功能&#xff1a; 一.完善集群更多功能1.1.可以扩展更多的功能 二.该系列课程代码地址三.技术栈及开发经验3.1.开发过程中所使用到的一些技术栈 四.开发过程中需要注意的事项五.反馈与交流 简介 该系列文章主要是介绍了多k8s集群平台开发的…

SF 不消费buffer

1、请求合成请求vsync MessageQueue.cpp 返回nextWakeupTime struct ArmingInfo { nsecs_t mActualWakeupTime; nsecs_t mActualVsyncTime; nsecs_t mActualReadyTime; }; 在schedule 请求vsync 时会根据算法计算出nextVsyncTime时间&#…

【matlab基础知识代码】(十二)逆矩阵与广义逆矩阵

>> Hhilb(4);H1inv(H),norm(H*H1-eye(4))H1 1.0e03 *0.0160 -0.1200 0.2400 -0.1400-0.1200 1.2000 -2.7000 1.68000.2400 -2.7000 6.4800 -4.2000-0.1400 1.6800 -4.2000 2.8000ans 2.8455e-13 矩阵维数较大&#xff0c;警告: 矩阵接近奇…

豆芽机置入语音芯片WTN6040-8S:开启智能生活新篇章,让豆芽制作更便捷有趣

豆芽机的开发背景&#xff1a; 豆芽作为一种营养丰富、味道鲜美的食品&#xff0c;深受广大消费者的喜爱。然而&#xff0c;传统的豆芽生产过程繁琐&#xff0c;需要耗费大量的时间和人力&#xff0c;且存在生产效率低、质量不稳定等问题。随着人们生活节奏的加快和对健康饮食的…

开源即时通讯IM框架 MobileIMSDK v6.5 发布

一、更新内容简介 本次更新为次要版本更新&#xff0c;进行了bug修复和优化升级&#xff08;更新历史详见&#xff1a;码云 Release Notes、Github Release Notes&#xff09;。 MobileIMSDK 可能是市面上唯一同时支持 UDPTCPWebSocket 三种协议的同类开源IM框架。轻量级、高…

django和vue开发的前后端分离网站怎么部署到服务器上,django和vue前后端分离网站怎么通过宝塔部署

提示&#xff1a;如果看完全部教程后仍然部署不成功&#xff0c;可以联系作者 一、提前准备 想要把django vue 前后端分离网站部署到服务器上&#xff0c;有一些提前准备的东西 1、备案域名&#xff08;域名必须备案&#xff09; 这里需要解析两个域名&#xff0c;一个前端&…