Spring核心和设计思想(1)

news2025/1/23 22:35:52

1.Spring是什么?

我们通常说的Spring指的是Spring FrameWork(Spring 框架),它是一个开源框架,有着活跃而庞大的社区,这就是它长久不衰的原因。Spring支持广泛的应用场景,它让Java企业级的应用程序开发起来更简单。在18年以前,开发大多使用的Spring框架,学会Spring框架我们就能维护公司以前写的代码。

Spring:包含了众多工具方法的IoC容器。

那么什么是容器?什么是IoC?什么是IoC容器?

1.1什么是容器?

按照我们的理解,容器是容纳某种物品的装置。

我们熟悉的有LinkedList,ArrayList等都可以被称为容器,容纳某种类型数据。

1.2什么是IoC?

IoC的全名是Inversion of Control翻译成中文“控制反转”的意思。那这句话到底什么意思呢?控制什么?反转什么呢?

1.2.1传统程序开发

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

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

/**
 * Describe:
 * User:lenovo
 * Date:2023-07-18
 * Time:10:39
 */
public class NewCarExample {
    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 = 30;
        public void init() {
            System.out.println("轮胎尺寸" + size);
        }
    }
}

传统的开发缺陷

在以上的程序中,轮胎的尺寸是固定的,但是随着对车需求的增大,个性化的需求也变得越来越多,这个时候我们就需要加工多种多样的轮胎,我们就对代码进行修改,如下所示:

/**
 * Describe:
 * User:lenovo
 * Date:2023-07-18
 * Time:10:39
 */
public class NewCarExample {
    public static void main(String[] args) {
        Car car = new Car(20);
        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);
        }
    }
}

以上程序的问题:当最下层的代码改动以后,整个调用链上的所有代码都发生了改动。

如何解决上述问题呢?

我们可以尝试不在每个类中创建自己的下级类,如果自己创建下级类就会出现这样的连锁反应。此时我们需要将自己创建的下级类,改为传递的方式(也就是注入的方式),因为我们不需要在当前类中创建下级类,所以下级类即使发生了变化(创建或减少参数),当前类也不用修改,这样就完成了程序的解耦了

PS:解耦指的是解决了代码的耦合性,耦合性也就可以换一种叫法叫程序的相关性。好的程序代码的耦合性(代码之间的相关性)是很低的。

1.2.2控制反转式程序开发

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

public class NewCarExample3 {
    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);
        }
    }
}

代码经过上面的调整,不论底层类如何变化,整个调用链式不用做任何更改的,这样就完成了代码之间的解耦

1.2.3对比总结规律

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

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

1.3理解Spring IoC 

回到刚刚说的那句话来,Spring是包含了多个工具方法的IoC容器。那它就具备两个基本的功能:

  • 将对象存放到容器中
  • 从容器中取出对象

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

将对象存放到容器中的好处:将对象储存在IoC容器相当于将以后可能会使用到的所用工具依次性制作好都放到仓库中,需要的时候直接取出来,用完再把它放回到仓库。而new对象的方式相当于,每次需要工具了,才现做,用完了就扔掉了,也不会保存,下次再使用的时候就需要重新做了,这就是IoC容器和普通程序开发的区别。

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

1.4DI概念说明

说到Ioc不得不提及一个词“DI”,DI的全称是Dependency Injection的缩写,翻译成中文是“依赖注入“的意思

依赖注入,就是由IoC容器在运行期间,如果需要一个对象,无须new创建,而是依赖外部的注入。

就如上面代码的例子,我们造一辆车需要车架,我们不要自己创建车架,而是传入一个车架类型的参数(相当于直接去拿一个现成的车架),这就是依赖注入

依赖注入(DI)和控制反转(IoC)是从不同地角度描述的同一件事情,就是指通过引入IoC容器,利用依赖关系注入的方式,实现对象之间的解耦。换句话来说,实现控制反转的实现方式之一是依赖注入

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

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

相关文章

SUNSET_DECOY靶机详解

SUNSET_DECOY靶机复盘 这个靶机还是有点难度的,尤其在提权时候,毫无思路。 下载地址:https://download.vulnhub.com/sunset/decoy.ova 首先扫描IP,打开网站,这个靶机我是没有扫描目录的,因为没给我机会扫…

3组6通道DRP通道USB PD3.1控制SOC芯片LDR6020P

前言 2021年5月,USB-IF 协会发布了全新的USB PD3.1规范,该规范将快充功率上限从100 W提升至240 W,充电功率的提升也让USB PD的应用从手机、笔记本电脑,扩展到便携式设备、物联网设备、智能家居、通信和安防设备、汽车和医疗等领域…

小研究 - 面向 Java 的高对抗内存型 Webshell 检测技术(三)

由于 Web 应用程序的复杂性和重要性, 导致其成为网络攻击的主要目标之一。攻击者在入侵一个网站后, 通常会植入一个 Webshell, 来持久化控制网站。但随着攻防双方的博弈, 各种检测技术、终端安全产品被广泛应用, 使得传统的以文件形式驻留的 Webshell 越来越容易被检测到, 内存…

浅谈一下自动化运维优点和缺点,哪款工具好?

面对越来越复杂的业务,以及越来越多样化的用户需求,IT运维的要求也越来越高,IT运维人员工作也越来越繁琐复杂,因此如何又快又安全的保障IT服务是重中之重。这个时候就需要用到自动化运维了。今天我们就来一起简单聊聊什么是自动化…

Linux中的动态库与静态库

文章目录 软链接与硬链接动态库与静态库静态库动态库 动静态库的区别 软链接与硬链接 软链接 当我们不在本地路径下运行时,运行目标二进制文件一般要写明该程序路径. 但是这样运行对于路径较为复杂的程序极为耗费时间,为了简便操作,我们可以将该可执行程序的路径设置为软链接.…

SQL函数和高级语句

目录 一、常用函数 1.聚合函数 2.数学函数 3.字符串函数 二、sql高级语句 1. SELECT(显示表格中指定字段或所有记录) 2.DISTINCT(不显示指定字段数据重复的记录) 3.WHERE(指定条件查询) 4.AND、OR…

(五)「消息队列」之 RabbitMQ 主题(使用 .NET 客户端)

0、引言 先决条件 本教程假设 RabbitMQ 已安装并且正在 本地主机 的标准端口(5672)上运行。如果您使用了不同的主机、端口或凭证,则要求调整连接设置。 获取帮助 如果您在阅读本教程时遇到问题,可以通过邮件列表或者 RabbitMQ 社区…

【树链+EXGCD】杭电多校第一场 A

1001 Hide-And-Seek Game (hdu.edu.cn) 题意: 给定一棵树和两条路径,每条路径都有起点和终点,起始时起点有人,每隔一秒都会往终点走一步,会从起点走向终点再会起点这样不断地周期性地走,让你求一点&#…

线上 OOM 频发,MyBatis 有坑...

继上次线上 CPU 出现了报警,这次服务又开始整活了,风平浪静了没几天,看生产日志服务的运行的时候,频繁的出现 OutOfMemoryError,就是我们俗称的 OOM,这可还行! 频繁的 OOM 直接会造成服务处于一…

编程小白的自学笔记十(python爬虫入门二+实例代码详解)

系列文章目录 编程小白的自学笔记九(python爬虫入门代码详解) 编程小白的自学笔记八(python中的多线程) 编程小白的自学笔记七(python中类的继承) 编程小白的自学笔记六(python中类的静态方法…

pandas 笔记:pivot_table 数据透视表

1 基本使用方法 pandas.pivot_table(data, valuesNone, indexNone, columnsNone, aggfuncmean, fill_valueNone, marginsFalse, dropnaTrue, margins_nameAll, observedFalse, sortTrue)2 主要参数 dataDataFramevalues要进行聚合的列index在数据透视表索引(index…

flask基本用法小白教程+按钮跳转到指定页面+python和pip安装(后附)

一、flask学习教程: 1.1 基本程序: 大家可以在pycharm中复制如下代码,先感受一下flask的基本用法: 点击链接可进入浏览器查看程序运行的结果,在127.0.0.1:5000后面添上/test1/等设定的文字,可查看不同函…

Python生成exe文件运行出现黑框闪退如何查看运行bug?

cmd进行回车 第一:进入到可执行exe文件目录,如下图所示 第二:输入可执行文件名,然后就会出现报错提示

(转载)BP神经网络的非线性系统建模(matlab实现)

1案例背景 在工程应用中经常会遇到一些复杂的非线性系统,这些系统状态方程复杂,难以用数学方法准确建模。在这种情况下,可以建立BP神经网络表达这些非线性系统。方法把未知系统看成是一个黑箱,首先用系统输入输出数据训练BP神经网络,使网络能够表达该未知函数,然后用训练好的 B…

【外卖系统】环境的搭建

搭建数据库 1.创建数据库,名字叫reiggie 2.导入数据库 创建Maven项目 1.创建项目 2.检查项目新建的是否有问题 3.导入pom.xml文件 4.导入application.yml文件 在从gittee上down的代码的基础上,修改一下端口号,数据库的名称什么的 …

(数组与矩阵) 剑指 Offer 29. 顺时针打印矩阵 ——【Leetcode每日一题】

❓ 剑指 Offer 29. 顺时针打印矩阵 难度:简单 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。 示例 1: 输入:matrix [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,6,9,8,7,4,5] 示例 2: 输…

DP转HDMI方案芯片-CS5218/CS5263/CS5363/CS5463详细参数对比说明

CS5218/CS5263/CS5363/CS5463都可用于设计DP转HDMI转接线方案,但几者间不管封装还是功能参数都有差异,如下介绍对比下: CS5218 DP to HDMI(4K30HZ) ,CS5218管脚定义参数说明和设计电路图: ​ ​ CS5263 DP to HDMI 4…

Kubernetes_1.27.3_Harbor结合Nacos实战

Nacos 实战 作者:行癫(盗版必究) 一:Nacos简介 1.简介 ​ Nacos是 Dynamic Naming and Configuration Service的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台;Nacos 致力于帮助您发现、配置和管理微服务;Nacos 提供了一组简单易用的特…

计讯物联5G千兆网关TG463在电力智能巡检机器人的应用功能解析

项目背景 随着国家智能电网建设加速推进,投资规模持续扩大,我国电网智能化、信息化不断提高,传统的电力运维与管理模式早已不能满足智能电网快速发展的需求。因此,在5G无线通信、人工智能、物联网、云计算、大数据、电力等前沿技术…

Error: The client is unauthorized due to authentication failure.解决办法

进入到neo4j的安装目录 修改neo4j.conf配置文件 把红框的注释#去掉保存后,重新运行neo4j,问题解决