Spring IoCDI (1)

目录

一、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.mfbz.cn/a/593883.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

分布式与一致性协议之ZAB协议(二)

ZAB协议 ZAB协议是如何实现操作地顺序性的? 如果用一句话解释ZAB协议到底是什么,我觉得它是能保证操作顺序性的、基于主备模式的原子广播协议。 接下来,还是以指令X、Y为例具体演示一下,帮助你更好地理解为什么ZAB协议能实现操作…

力扣每日一题113:路径总和||

题目 中等 给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例 1: 输入:root [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSu…

【R语言数据分析】函数

目录 自定义函数 apply函数 分类汇总函数aggregate 自定义函数 R语言中的自定义函数更像是在自定义一种运算规则。 自定义函数的语法是 函数名 函数体 } 比如 表示定义了一个名为BMI_function的函数,这个函数代表了一种运算规则,就是把传入的x和…

stm32开发之netxduo网口通讯,网线热插拔处理

前言 在使用netxduo组件时,如果在上电过程中,未插入网线,eth驱动使能过程中未正常初始化本次使用以下几种方式进行设置 问题原因 使用定时器事件回调方式 网络组件中进行调整 /** Copyright (c) 2024-2024,shchl** SPDX-Licen…

openGL

open Graphics Library 核心是一个c库,同时支持多语言的派生。 可编程管线, 状态机(State Machine)是一种数学模型,用于描述对象在不同状态下的行为及状态之间的转换关系。状态机由一组状态(States&#…

2010NOIP普及组真题 2. 接水问题

线上OJ: 一本通:http://ybt.ssoier.cn:8088/problem_show.php?pid1950 解法一、朴素模拟 核心思想: 朴素模拟: 1、先给每个b[i]水龙头分配一个人a[i],b[i] 表示水龙头的剩余时间。同时标记该水龙头为 used 使用中 2…

深入解析:匹配网络(Matching Networks)的原理和应用

匹配网络(Matching Networks) 深入解析:匹配网络(Matching Networks)的原理和应用匹配网络的核心原理工作原理算法流程 匹配网络的实现应用示例结论 深入解析:匹配网络(Matching Networks&#…

01_SpringBoot简单搭建入门程序

目录 1、先创建一个java项目2、导入依赖3、将Java项目修改为SpringBoot项目4、编写一个测试的Controller5、测试(创建一个*.http的文件)方式1:方式2:可以直接在浏览器访问该地址方式3:使用postman也可以 1、先创建一个java项目 我的项目结构…

FlinkSql使用ES sink并指定主键,为什么数据还是会被覆盖?

FlinkSql使用ES sink并指定主键,为什么数据还是会被覆盖? 1. 问题描述 根据ES connector文档中的描述,创建ES表并指定主键后将采用upsert模式。 但是在实际的使用过程中却发现部分数据仍然存在被直接覆盖的问题。 举个例子,假如…

NumPy库与PyTorch库的异同点

目录 1.单位的创建和操作 1.创建 2.形状变换 2.数学和统计操作 1.矩阵乘法 2.广播 3.统计计算 3.GPU支持 4.在深度学习中的作用 5.应用范围 NumPy库为数组服务,PyTorch库为张量服务,这是最本质的区别。 1.单位的创建和操作 1.创建 NumPy:使…

【busybox记录】【shell指令】md5sum

目录 内容来源: 【GUN】【md5sum】指令介绍 【busybox】【md5sum】指令介绍 【linux】【md5sum】指令介绍 使用示例: 128位MD5 - 默认输出 128位MD5 - 将每个文件当做二进制处理 128位MD5 - 从文件中读取MD5值并做检查 128位MD5 - 创建一个BSD风…

浅谈OpenCV 粗略计算工件轮廓面积和外接圆直径(Emgu.CV)

前言 最近领导在做库房工具管理这块的功能,希望能集成OpenCV 粗略的计算出工具的长度,以方便用户再归还工具的时候,提示用户该放在那种尺寸的盒子里面,这便是这篇文章的由来。 我们的系统是基于.net开发的,所以采用的是…

项目管理-项目采购管理1/2

项目管理:每天进步一点点~ 活到老,学到老 ヾ(◍∇◍)ノ゙ 何时学习都不晚,加油 1.项目采购管理-主要内容 项目采购管理过程--重点: ①ITTO 输入,输出工具和技术。 ②问题和解决方案。 ③论文…

【白话机器学习系列】白话特征向量

白话特征向量 一个方阵 A A A 与列向量 v v v 的乘积会生成一个新的列向量。这个新向量通常与原向量有着不同的方向,矩阵在这里代表一个线性变换。然而,某些向量会保持其原始方向。我们称这种向量为矩阵 A A A 的特征向量(eigenvector&…

python数据分析——业务指标分析

业务指标分析 前言一、业务指标分析的定义二、业务问题构建问题构建的要求 三、业务问题的识别在识别问题的阶段对于企业内部收益者的补充: 四、竞争者分析标题竞争者分析的内容:标题竞争者分析目的:案例: 黑莓公司为什么会消亡&a…

dynamic_cast 静态转换

dynamic_cast 静态转换 const_cast 常量转换 重新解释转换(reinterpret_cast) 最不安全

RocketMq详解:一、RocketMQ 介绍及基本概念

文章目录 前言1.RocketMQ简介2.RocketMQ 特点3.核心特性4.应用场景5.RocketMQ 优势6.RocketMQ 四大核心组件6.1 NameServer1.NameServer作用2.NameServer被设计为无状态的原因3.和NameServer和Zookeeper的区别4.NameServer的高可用保障 6.2 Broker1.Broker部署方式2.高可用与负…

ssm105基于JAVAEE技术校园车辆管理系统+jsp

校园车辆管理系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本校园车辆管理系统就是在这样的大环境下诞生,其可以帮助管理者在短…

泰克示波器电流探头如何抓浪涌电流波形?

泰克示波器是一种常见的电子测量仪器,广泛应用于电子工程、通信工程、医疗设备等领域。它的主要功能是实时显示电信号的波形,从而帮助工程师和技术人员分析和调试电路。而在一些特定的应用场景中,例如电源、电机、电器设备等,我们…

模型全参数训练和LoRA微调所需显存的分析

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…
最新文章