【Spring】学习Spring需要掌握的核心设计思想

news2024/11/17 13:54:14

目录

一、Spring是什么

二、什么是IoC容器

1、什么是容器

2、什么是IoC 

 3、Spring IoC

4、DI(依赖注入)

4.1、IoC和DI的区别

5、 DL(依赖查找)


一、Spring是什么

我们通常所说的Spring指的是Spring Framework(Framework的意思就是框架),它是一个开源的框架,有着庞大的社区,这就是它之所以能长久不衰的原因,Spring支持广泛的应用场景,它可以方Java企业级的应用程序开发起来更简单。

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

二、什么是IoC容器

1、什么是容器

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

我们之前了解的List和Map,他们都是用来装数据的容器,这写容器把我们需要常用到的方法都已经封装好了,我们只需要知道如何使用并且知道使用什么方法可以达到我们想要实现的效果即可。还有Tomcat是一个Web容器。同理Spring就是一个IoC容器。

2、什么是IoC 

IoC是Inversion of Control的缩写,直译的意思是"控制翻转"的意思,这是一种思想,实际上IoC表示的意思为"控制权翻转"。之前我们写的代码中对象的生命周期,是由程序员或者当前的代码片段控制的;而控制权翻转就是程序中对象的生命周期不在又程序员或者当前的代码片段控制,而是由Spring(IoC容器)来控制。

下面我们通过一个例子来了解这个IoC容器

1️⃣传统代码的写法

我们都知道构造一个汽车,首先这个车需要依赖于车身(FrameWork),而车身需要依赖于底盘(Bottom),而底盘需要依赖于轮胎(Tire),这就需要我们在写代码的时候在底盘的类中new一个轮胎的对象,在车身的类中new一个底盘的对象,在车的类中需要new一个车身的对象。

 我们的车肯定有不同的款式,当我们对车的组成所依赖的对象中的属性做出指定(个性化需求)的时候,一个类添加属性的时候,其他依赖(new)这个类的类,在new对象的时候都需要进行修改。

package old;
//汽车类
public class Car {
    private Framework framework;
    public Car(){
        framework = new Framework();
    }
    public void init(){
        //依赖车身
        System.out.println("构造汽车");
        framework.init();
    }
}

package old;
//车身类
public class Framework {
    private Bottom bottom;
    public Framework(){
         bottom = new Bottom();
    }
    public void init(){
        System.out.println("构建车身");
        //依赖底座
        bottom.init();
    }
}

package old;
//底盘类
public class Bottom {
private Tire tire;
    public Bottom(){
        Tire tire = new Tire();
    }
    public void init(){
        System.out.println("构建底盘");
        //依赖轮胎
        tire.init();
    }
}

package old;
//轮胎类
public class Tire {
    private int size = 20;//轮胎尺寸
    public void init(){
        System.out.println("轮胎尺寸:"+size);
    }
}

package old;
//测试类,用来创建一个汽车对象
public class Test {
    public static void main(String[] args) {
        Car car = new Car();
        car.init();
    }
}



当我们在创建这个车对象时想要这个车的轮胎尺寸小一点,这个时候就需要我们对轮胎类中的构造方法进行改造,让我们在创建车这个对象的时候,可以直接直接指定车的轮胎大小,如果想修改车的颜色,我们就需要在车身类中添加一个颜色的属性,但是这个构造方法改变之后,对应的之后的类中new的对象的操作都选要进行改变。

package old;

public class Car {
    private Framework framework;
    public Car(int size,String color){
         framework = new Framework(size,color);
    }
    public void init(){
        System.out.println("构造汽车");
        //依赖车身
        framework.init();
    }
}

package old;

public class Framework {
    private Bottom bottom;
    public String color ;
    public Framework(int size,String color){
         bottom = new Bottom(size);
         this.color = color;
    }
    public void init(){
        System.out.println("车身颜色:"+color);
        //依赖底座
        bottom.init();
    }
}


package old;

public class Bottom {
    private Tire tire;
    public Bottom(int size){
        tire = new Tire(size);
    }
    public void init(){
        System.out.println("构建底盘");
        //依赖轮胎

        tire.init();
    }
}

package old;

public class Tire {
    private int size = 20;
    public Tire(int size){
        this.size = size;
    }
    public void init(){
        System.out.println("轮胎尺寸:"+size);
    }
}

package old;

public class Test {
    public static void main(String[] args) {
        Car car = new Car(12,"red");
        car.init();
    }
}

可以看见上述的代码是"牵一发而动全身",当最底层代码改动之后,整个调用链上的所有代码都需要改动,这就是代码中的耦合性太高而导致的。

2️⃣使用IoC思想实现的代码

解决这个问题,我们可以使用IoC的思想来实现代码,我们只需要将原来自己创建的下级类,改为传递的方式(也就是注入的方式),我们在上级类中用构造方法的参数来申明这个类需要使用它的下级类。不在这个类中new这个下级类的对象,而是在Test类中统一的使用构造方法来创建这些类的对象。

package ioc;

//汽车类
public class Car {
    private Framework framework;
    public Car(Framework framework){
        this.framework = framework;
    }
    public void init(){
        System.out.println("car init");
        framework.init();
    }
}


package ioc;

//车身类
public class Framework {
    private Bottom bottom;
    public Framework(Bottom bottom){
        this.bottom = bottom;
    }
    public void init(){
        System.out.println("Framework init");
        bottom.init();
    }
}


package ioc;

//底盘类
public class Bottom {
    private Tire tire;
    public Bottom(Tire tire){
        this.tire = tire;
    }
    public void init(){
        System.out.println("Tire init");
        tire.init();
    }
}

package ioc;

//轮胎类
public class Tire {
    private int size = 20;
    public void init(){
        System.out.println("Tire init,size:"+size);

    }
}

package ioc;
/*
 * 模拟IoC容器,这个类中的Test构造方法,可以认为是Spring中进行的操作,我们无需关注
 * 只需要关注前面创建的汽车类。
 * */
public class Test {
    private Tire tire;
    private Bottom bottom;
    private Framework framework;
    private Car car;
    public Test(){
        this.tire = new Tire();
        this.bottom = new Bottom(this.tire);
        this.framework = new Framework(this.bottom);
        this.car = new Car(this.framework);
    }

    public static void main(String[] args) {
        Test test = new Test();
        test.car.init();
    }
}

可以将这个Test类中除了main方法之外的认为是Spring框架也就是IoC容器,Test构造方法中的这些内容都是在这个容器中实现好的,我们使用Spring是无需关注,只需要关注我们创建的类中需要添加和修改的属性。就比如我们想要车身为红色,只需要在Framework类中,添加一个color属性,构造这个类的构造方法的时候,需要对这个color属性添加一个初始化的操作即可。也不需要修改这个调用链上的其他类。

从这里也就可以看出我们将控制权翻转了,将控制权交给了容器,程序员不在控制这些对象的生命周期。

 可以看见我们创建的车的对象,想要修改一些属性,只需要修改对应的类中的构造方法,之后的都是有Test类中,也就是容器中设置车的属性即可。不在需要调整整个调用链,这就达到了解耦合的效果。

✨总结:

  • 传统的代码中类的实现是上级类控制着下级类,下级类对象的创建和销毁都是由上级类控制,也就是程序员控制。而改进之后的解耦合的代码中上级类不在控制下级类对象的创建和销毁,而是把下级对象注入到当前的对象中,下级对象的控制权不在由上级类控制,这样即使下级类发生了任何变化,上级类都是不受影响的,这就是IoC的实现思想。
  • IoC的好处就是,对象的生命周期(对象的创建和销毁)不再由程序员来控制,而是交给了IoC容器也就是由Spring框架来处理,实现了解耦,使程序的可维护性提高。

 3、Spring IoC

Spring是包含了多个工具方法的IoC(控制反转)容器,他是一个容器,那么就存在最基本的两个功能。

  1. 将对象(Bean)存入Spring容器中;
  2. 从Spring容器中取出对象(bean);

将对象存放到容器中的好处:将对象存储到IoC容器相当于将以后可能用的所有工具制作好都放在仓库中,需要的时候直接取就可以,用完了再把它放回到仓库,而new对象的方式相当于,每次需要工具的时候, 都需要现场从0开始制作,使用完成之后,将这个工具不保存直接扔掉,下次使用的时候再创建,这就是IoC容器和普通程序开发的区别。

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


4、DI(依赖注入)

DI是Dependency Injection的缩写,翻译成中文就是"注入依赖"的意思。

所谓依赖注入,就是由IoC容器再运行期间,动态的将某种依赖关系注入到对象之中。就像我们之前的IoC思想代码,在运行Car类的时候,需要的依赖的是Framework类,他会再容器中找到,并赋值给Car类中的framework属性。这个过程就是动态的将依赖注入到对象中,这也就是依赖注入。

4.1、IoC和DI的区别

  • 相同点:IoC和DI是从不同的角度描述了同一间事情,就是指通过引入IoC容器,利用依赖关系注入的方式,实现对象之间的解耦。
  • 不同点:IoC是"目标"也是一种设计思想,而且目标和思想只是一种指导原则,最终还是要有可行的落地方案,而DI就是IoC的一种具体实现。

5、 DL(依赖查找)

依赖查找(DL)也是IoC(控制翻转)的一种实现方式,DL是Dependency Lookup的简称。

在依赖查找中,对象负责查找她所依赖的对象,而不是将依赖关系委托给容器。容器只负责管理大对象的生命周期,而不负责对象之间的依赖关系。

依赖注入和依赖查找的区别在于,依赖注入是将依赖关系委托给容器,由容器来管理兑现之间的依赖关系;而依赖查找是由对象自己来查找他所依赖的对象,容器只负责管理对象的生命周期。

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

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

相关文章

DAY55:单调栈(一)每日温度+下一个更大元素Ⅰ

文章目录 739.每日温度栈数据结构单调栈思路单调栈原理单调栈注意点判断条件工作过程分析 完整版 496.下一个更大元素Ⅰ思路映射思路 完整版总结 739.每日温度 给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 an…

2023年第四届“华数杯”数学建模思路 - 案例:异常检测

文章目录 赛题思路一、简介 -- 关于异常检测异常检测监督学习 二、异常检测算法2. 箱线图分析3. 基于距离/密度4. 基于划分思想 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 一、简介 – 关于异常检测 异常…

【Java】UWB高精度工业人员安全定位系统源码

基于VueSpring boot前后端分离架构开发的一套UWB技术高精度定位系统源码。 UWB高精度人员定位系统提供实时定位、电子围栏、轨迹回放等基础功能以及各种拓展功能,用户可根据实际需要任意选择搭配拓展功能。该系统简易部署,方便使用,实时响应。UWB高精度定…

Java on Azure Tooling 6月更新|标准消费和专用计划及本地存储账户(Azurite)支持

作者:Jialuo Gan - Program Manager, Developer Division at Microsoft 排版:Alan Wang 大家好,欢迎阅读 Java on Azure 工具的六月更新。在本次更新中,我们将介绍 Azure Spring Apps 标准消费和专用计划支持以及本地存储账户&…

二叉树迭代遍历

PS:以下代码均为C实现 1.二叉树前序遍历 力扣 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。 class Solution { public:vector<int> preorderTraversal(TreeNode* root) {stack<TreeNode*> st;vector<int> str;TreeNode* curroot;whil…

【波浪动态特效】基于jquery实现页面底部波浪动画效果(附完整源码下载)

文章目录 写在前面涉及知识点实现效果1、搭建页面1.1、创建两个片区1.2、创建波浪区域1.3、静态页面源码 2、JS实现波浪效果2.1 动画原理2.2 动画源码 3、源码分享3.1 百度网盘3.2 123云盘3.3 邮箱留言 总结 写在前面 想必搭建过企业官网的大多数对这个效果不陌生吧&#xff0…

备战秋招 | 笔试强训21

目录 一、选择题 二、编程题 三、选择题题解 四、编程题题解 一、选择题 1、设一个有序的单链表中有n个结点&#xff0c;现要求插入一个新结点后使得单链表仍然保持有序&#xff0c;则该操作的时间复杂度&#xff08;&#xff09; A. O(log2n) B. O(1) C. O(n2) D. O(n) 2…

网络中通过IP地址查找位置

display ip routing-table 查看路由表 display vlan 查看vlan 信息 display stp brief 查看生成树信息 display mac-address 查看mac 地址表 display arp 查看arp表 SW1 SW2

海量小文件传输慢的原因以及对应的优化方案

在日常工作中&#xff0c;我们经常遇到需要传输一些小文件的情况&#xff0c;但是当小文件的数量很多的时候&#xff0c;为什么小文件传输的速度就会变得很慢呢&#xff1f;为什么复制许多较小的文件时&#xff0c;小文件传输效率就会降低呢&#xff1f;针对这些问题&#xff0…

MyBatis查询数据库(3)

前言&#x1f36d; ❤️❤️❤️SSM专栏更新中&#xff0c;各位大佬觉得写得不错&#xff0c;支持一下&#xff0c;感谢了&#xff01;❤️❤️❤️ Spring Spring MVC MyBatis_冷兮雪的博客-CSDN博客 前面我们讲解了MyBatis增删改查基本操作&#xff0c;下面我们来深入了解M…

谷歌语音助手战略调整:开发 AI 新版,调整裁员计划

北京时间8月2日晚间&#xff0c;谷歌通过对 “谷歌助手” 团队进行调整和裁员&#xff0c;意图改变其开发方向。经过此次变动&#xff0c;谷歌计划借助最新的生成式人工智能技术和大型语言模型来提升 谷歌助手 的能力。此次调整表明语音助手市场未达到先前的预期。 亚马逊旗下的…

PT Industrial Security Incident Manager 扩展了对 Emerson 和 GE Fanuc 控制器的支持

&#x1f504; 我们发布了 PT Industrial Security Incident Manager (PT ISIM) 深度流程流量分析系统的下一套专业知识。 有哪些新功能&#xff1f; 1. 改进了 GE Fanuc (Emerson) GE-SRTP 协议的操作。该协议专为 GE Fanuc 控制器与工程软件&#xff08;Proficy Machine E…

ArmSoM-W3之RK3588安装Qt+opencv+采集摄像头画面

1. 简介 场景&#xff1a;在RK3588上做qt开发工作 RK3588安装Qtopencv采集摄像头画面 2. 环境介绍 这里使用了OpenCV所带的库函数捕获摄像头的视频图像。 硬件环境&#xff1a; ArmSoM-RK3588开发板、&#xff08;MIPI-DSI&#xff09;摄像头 软件版本&#xff1a; OS&…

angular框架——node_modules引入ng-zorro-antd问题

发生错误 在安装npm包&#xff08;ng-zorro-antd&#xff09;的时候&#xff0c;报错如下 原因 项目依赖的ng-zorro-antd版本号和引用包的17.0.2版本号不一致&#xff0c;项目使用的16.13.1版本号太高了&#xff0c;无法解析依赖树中低版本。 解决方案 &#xff1a; 命令修…

pointpillars的demo过程记录

1、进入pp conda activate pp 2、cd到/home/fyy/OpenPCDet-master/tools打开终端 python demo.py --cfg_file cfgs/kitti_models/pointpillar.yaml --ckpt /home/fyy/OpenPCDet-master/pointpillar_7728\ \(1\).pth --data 000009.bin 直接就可以demo显示了

数据库同步时,通过存储过程找出时间内发生变化的视图和物化视图

1. 应用场景 在软件开发或数据库运维过程&#xff0c;每一次数据库同步都是运维人员的痛苦的过程。 如果每次都是无脑全量更新&#xff0c;则工作量较大如果每次都是增量更新&#xff0c;则需要知道哪些视图谁在什么时候修改了&#xff0c;增加了什么信息&#xff08;因为往往…

(学习笔记-内存管理)内存满了会发生什么?

内存分配过程 应用程序通过 malloc 函数申请内存的时候&#xff0c;实际上申请的是虚拟内存&#xff0c;此时并不会分配物理内存。 当应用程序读写了这块虚拟内存&#xff0c;CPU就会去访问这个虚拟内存&#xff0c;这时会发现这个虚拟内存没有映射到物理内存&#xff0c;CPU…

【WiFi】国产WiFi芯片

目录 1.概述 2.WiFi芯片的市场格局 3.中国的WiFi芯片公司 3.1.华为海思 3.2.乐鑫科技 3.3.博通集成 3.4.紫光展锐 3.5.康希通信 3.6.南方硅谷 4.国产WiFi芯片竞争格局 4.1.内卷WiFi 4 4.2.缺席WiFi 5 4.3.发力WiFi 6 4.4.逐鹿WiFi 7 5.不得不提的WiFi FEM 1.概述…

视频创作者福音,蝰蛇峡谷NUC12SNKI7视频剪辑测评

英特尔NUC绝对是PC市场里最为特殊的产品&#xff0c;相比众多OEM设计制造的台式机而言&#xff0c;英特尔NUC主打小体积、高度集成化、强扩展性以及尽可能优异的性能表现。尤其是在主打游戏体验的NUC产品出现之后&#xff0c;更是将极致体验演绎到了极致。 在搭载独显的幻影峡谷…

Python爬虫教程篇+图形化整理数据(数学建模可用)

一、首先我们先看要求 1.写一个爬虫程序 2、爬取目标网站数据&#xff0c;关键项不能少于5项。 3、存储数据到数据库&#xff0c;可以进行增删改查操作。 4、扩展&#xff1a;将库中数据进行可视化展示。 二、操作步骤&#xff1a; 首先我们根据要求找到一个适合自己的网…