Spring 核心与设计思想 · Spring IoC容器 · 控制反转式程序开发 · DI概念

news2024/10/7 2:25:32

  • Spring 是什么?
  • 一、什么是容器?
  • 二、什么是 IoC?
    • 2.1 传统程序开发
    • 2.2 控制反转式程序开发
    • 2.3 对比总结规律
  • 三、理解 Spring IoC
  • 四、DI 概念说明

Spring 是什么?

我们通常说的 Spring 是指 Spring Framework(Spring 框架),它是一个开源的框架,有着活跃而庞大的社区,这就是它长久不衰的原因。

Spring 支持广泛的应用场景,它可以让 Java 企业级的应用程序开发起来更加简单。

用一句话概括 Spring:Spring 是包含了众多工具方法的 IoC 容器。


一、什么是容器?

容器是用来容纳某种物品的基本装置。——来自:百度百科

Java 中的容器有哪些?例如:
List / Map -> 数据存储容器
Tomcat -> Web 容器


二、什么是 IoC?

Spring 也是一个容器,Spring 是什么容器呢?Spring 是一个 IoC 容器。

什么是 IoC?
IoC = Inversion of Control 翻译成中文是 “控制反转” 的意思,也就是说 Spring 是一个 “控制反转” 的容器。

什么是 “控制反转” 容器?我将举例演示一下。

2.1 传统程序开发

我们现在要构建一辆 “车” 的程序,我们的实现思路是这样的:

构建一辆车(Car),车需要依赖车身(FrameWork),而车身需要依赖底盘(Bottom),而底盘需要依赖轮胎(Tire),最终程序的实现代码如下:

	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 = 20;
        public void init(){
            System.out.println("轮胎尺寸:" + size);
        }
    }

传统程序开发的缺陷
以上程序中,轮胎的尺寸是固定的。然而在现实生活中,对汽车的需求量越来越大,个性化也会越来越多,不可能一直使用同一种尺寸的轮胎。
这时候就需要对上面的程序进行修改了…

	public static void main(String[] args) {
        Car car = new Car(18);
        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);
        }
    }

显然这样的修改,付出的代价是蛮大的。最底层代码改动后,整条调用链上的所有代码都需要修改。

如何解决上述的问题呢?

我们可以尝试不在每个类中自己创建下级类,如果自己创建下级类就会出现当下级类发生改变操作,自己也要跟着修改。

此时,我们只需要将原来由自己创建的下级类,改为传递的方式(也称为注入的方式)。因为我们不需要在当前类中创建下级类了,所以下级类即使发生改变(创建或者减少参数),当前类本身也无需修改如何代码,这样就完成了程序的解耦。

就例如:
我们创造一辆完整的汽车,如果所有的配件都是自己打造,那么当客户需求发生改变的时候,轮胎尺寸改为 21 寸,车漆改为欧泊银,这时候我们只能再次手动来改。但如果我们是把轮胎外包出去,那么即使轮胎的需求发生改变,我们只需要向代理工厂下订单就行了,我们自身是不需要出力的。


2.2 控制反转式程序开发

基于以上的思路,我们把调用汽车的程序示例修改一下,把创建子类的方式,改为注入传递的方式~

public static void main(String[] args) {
        Tire tire = new Tire(20);
        Bottom bottom = new Bottom(tire);
        Framework framework = new Framework(bottom);
        Car car = new Car(framework);
        car.init();
    }

    //汽车对象
    static class Car{
        private Framework framework;

        public Car(Framework framework){
            this.framework = framework;
        }

        public void init(){
            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);
        }
    }

感觉各个类都不相互影响,只有到了 main 方法中,才把每个类提供的零件组装起来成为一辆汽车。

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


2.3 对比总结规律

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

传统代码是 Car 控制并创建了 Framework,Framework 控制并创建了 Bottom,依次往下。
改进之后的控制权发生了反转,不再是上级对象创建并控制下级对象了,而是下级对象注入到当前对象中,下级的控制权不再是上级类掌控,这样即使下级类发生了改变,当前类和上级类都是不受影响的,这就是典型的控制反转,也就是 IoC 的实现思想


三、理解 Spring IoC

回到我们一开始的主题 Spring,Spring 是包含了多个工具方法的 IoC容器,这就是对 Spring 最核心的总结。

如何理解 “Spring 是一个 IoC 容器” 这句话?
既然 Spring 是一个 IoC(控制反转)容器,重点还是在 “容器” 二字上,那么它就具备两个最基本的功能:
① 将对象存储到容器中;
② 从容器中取出对象。

也就是说学 Spring 最核心的功能,就是学会如何将对象存储到 Spring 中,再从 Spring 中获取对象的过程

将对象存放到容器中的好处:
将对象存储到 IoC 容器相当于将以后可能用到所有工具制作好都放到仓库中,需要直接取,用完再把它放回仓库。

而 new 对象的方式相当于,每次需要工具,现场做,用完就直接扔掉了,下次再用的时候还得重新做。

这就是 IoC 容器和普通程序开发的区别。

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


四、DI 概念说明

提到 IoC 不得不提另一个词,就是 “DI”,DI 是 Dependency Injection 的缩写,翻译成中文是 “依赖注入” 的意思。

所谓依赖注入,就是由 IoC 容器在运行期间,动态地将某种依赖关系注入到对象之中。所以,依赖注入(DI)和控制反转(IoC)是从不同的角度描述同一件事情,就是指通过引入 IoC 容器,利用依赖关系注入的方式,实现对象之间的解耦。

IoC 是一种思想或是一个目标,最终还是要有可行的落地方案,而 DI 就是属于具体的实现。 例如今天心情好,去喝杯奶茶(是思想和目标 IoC),最后去茶百道选了芋圆奶茶(是具体的实现 DI)。

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

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

相关文章

【Mysql】知识体系结构构建以及常见考题汇总

【Mysql】知识体系结构构建以及常见考题汇总1、基本SQL知识1.1、D_L语法以及表中常用约束1.2、mysql表列常用数据结构1.3、事务(此处展示并发事务问题以及解决方案、实现原理见2.3)read uncommitted有脏读问题read committed解决脏读、有不可重复读问题r…

Android基础学习(二十)—— 线程安全

1、Android中线程的常见用法 (1)继承 Thread class MyThread extends Thread{Overridepublic void run(){//处理具体的逻辑} } new MyThread().start(); //启动此线程//使用匿名类 new Thread(){Overridepublic void run(){//处理具体的逻辑} }.star…

【加油站会员管理小程序】03 创建应用

我们上一篇介绍了数据源的创建,本篇我们介绍应用的创建。 微搭低代码中一共有两类应用,一类是数据模型应用,一类是自定义应用。数据模型应用往往对应着PC端的管理后台,例如我们的小程序通常需要一个管理后台来录入数据。 自定义…

【linux】2022年还能用,网易真的是良心啊,网易云音乐linux版本现在还是可以使用的超赞!!官方网的下载地址还可以使用,音乐使用的是qt5进行开发的。

目录前言1,关于网易云音乐2,可以正常使用,可以登录前言 本文的原文连接是: https://blog.csdn.net/freewebsys/article/details/128261513 未经博主允许不得转载。 博主CSDN地址是:https://blog.csdn.net/freewebsys 博主掘金地址…

vue.js:父子组件的实训案例

作业需求 需求1:定义两个输入框,通过输入框输输入的值改变页面显示的值需求2:改变第一个输入框的值的同时使得第二个输入框的值变为100倍并显示需求3:改变第二个输入框的值的同时使得第一个输入框的值变为1/100并显示 实训代码实…

CentOS搭建基于ZIPKIN的数据追踪系统

ZipKin入门介绍 Zipkin是一款开源的分布式实时数据追踪系统(Distributed Tracking System),基于 Google Dapper的论文设计而来,由 Twitter 公司开发贡献。其主要功能是聚集来自各个异构系统的实时监控数据。分布式跟踪系统还有其…

TinUI4.0发布

引言 TinUI4登场~~~ 更新一览: 优化radiobox效果修复listview返回元素不全的问题新增树状图 treeview使用TinUI LOGO.ico新增普通图片 image随包发布 TinUI帮助手册 实用程序,在\test目录下 修复 这是常规更新,修复了listview创建过程中…

ChatGPT怎么用

最开始了解ChatGPT居然是抖音上看到的,之前了解过GPT-3,最开始认为可能类似的语言模型,上手以后才发现,这玩意挺有意思,某些方面,比百度强,但是比人还差十万八千里,智力不好说&#…

【Proteus仿真】【STM32单片机】智能浴室水温调控仪设计

文章目录一、功能简介二、软件设计三、实验现象联系作者一、功能简介 本项目使用Proteus8仿真STM32单片机控制器,使用LCD1602、DS18B20、继电器加热、电机模块等。 系统运行后,LCD1602显示DS18B20采集温度值、温度上限阈值。 开启加水,一段…

PostgreSQL实战之物理复制和逻辑复制(四)

目录 PostgreSQL实战之物理复制和逻辑复制(四) 4 流复制监控 4.1 pg_stat_replication 4.2 监控主备延迟 4.3 pg_stat_wal_receiver PostgreSQL实战之物理复制和逻辑复制(四) 4 流复制监控 4.1 pg_stat_replication 主库上主…

Dual-Path Fusion:遥感融合

DPFN: A Dual-Path Fusion Network for Pan-Sharpening (一种用于泛锐化的双路径融合网络) 大多数现有深上用于pan-sharpening方法的几个公认的问题,如光谱失真和足够的空间纹理增强。针对这些问题,提出了一种新的双路径融合网络…

浙大全日制英文MBA项目申请的五大关键词

2023级开始,浙大全日制英文MBA项目全面登场!对于这个项目的了解,大多数考生还不是特别清楚,因为很多考生更加关注的是“全日制”而非英文MBA本身的情况,如果还是带着以往对中文全日制MBA项目的理解来申请这个项目&…

《Linux运维实战:使用Percona Server for MongoDB物理备份与恢复Mongodb数据》

一、备份与恢复方案 Percona Server for MongoDB 是一个免费的、增强的、完全兼容的、源代码可用的、带有企业级功能的MongoDB Community Edition的替代品。它不需要对MongoDB应用程序或代码进行更改。Percona Server for MongoDB支持版本 > 3.6 。 说明:当前环…

【通知】《生成对抗网络GAN原理与实践》代码开源,勘误汇总!

有三上个月出版了新书《生成对抗网络GAN:原理与实践》,Generative Adversarial Networks(中文名生成对抗网络,简称GAN)自从被提出来后,其发展就非常迅猛,几乎已经被应用于所有CNN可以使用的领域…

Js逆向教程21-vscode无环境联调

作者:虚坏叔叔 博客:https://xuhss.com 早餐店不会开到晚上,想吃的人早就来了!😄 Js逆向教程21-vscode无环境联调 一、环境安装 电脑安装visual code 电脑安装node.js 二、nodejs环境调试 vscode打开一个文件夹并创…

valet-windows

现在win可以用valet了,安装开始 环境参考 1》安装PHP 版本7.4.32 2》安装composer 2.4 安装valet 1》composer global require cretueusebiu/valet-windows 2》valet install 3》这里有2中方法,本人选择link valet link [name] 浏览器中输入 name.te…

[附源码]计算机毕业设计健身房预约平台Springboot程序

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

20221210英语学习

今日新词: authorize v.授权, 批准 layoff n.临时解雇, 操作停止, 活动停止期间 jazz adj.爵士音乐的, 不调和的, (色彩等)花哨恶俗的 overlap v.(与…)交叠,部分重叠;时间交叠;有共同之处 subject n.…

Matlab中的数据类型

数据类型 MATLAB中的数据类型主要包括数值类型、逻辑类型、字符串、函数句柄、结构体和
单元数组类型。这6种基本的数据类型都是按照数组形式存储和操作的。另外,MATLAB
中还有两种用于高级交叉编程的数据类型,分别是用户自定义的面向对象的用户类类型…

【考研数据】二.2021年BJTU计算机学院考研录取数据分析

欢迎订阅本专栏:《北交计算机复试经验》 订阅地址:https://blog.csdn.net/m0_38068876/category_12110003.html 【考研数据】一.2020年BJTU计算机学院考研录取数据分析【考研数据】二.2021年BJTU计算机学院考研录取数据分析【考研数据】三.2022年BJTU计算机学院考研录取数据分…