Spring框架学习 -- 核心思想

目录

(1) Spring是什么?

(2) 什么是IOC容器?

(3) 从传统开发认识spring

(4) 这种传统开发的缺陷

(5)解决传统开发中的缺陷

(6) 对比总结规律

(7) 理解IOC 


创作不易多多支持


(1) Spring是什么?

        我们常说的Spring的全称是: Spring Framework(Spring框架), 它是一个开源的框架, 有着活跃而且庞大的社区, 这就是它之所以能长久不衰的原因, Spring 支持广泛的应用场景, 他可以让java企业级的应用程序开发变得非常简单

        用一句话概括就是, Spring是包含了众多工具方法的IOC容器

(2) 什么是IOC容器?

        想到容器我们就可以和java的集合体系来做对比, 集合体系里面, 就拿list类来讲, list里面设置泛型之后就可以存放对应的数据, 相同的包括我们曾经使用的tomcat也是如此, tomcat是一个web应用程序的容器, 它负责将webApp发布到网络.

(3) 从传统开发认识spring

         假如我们要构建一辆车的程序, 我们可以思考一下, 一辆车需要以下这几个部件:

  • 车身(Framework)
  • 底盘(Bottom)
  • ......(中间还可以有很多部件,这里只列举几个即可)
  • 轮胎(Tire)

        上面的三个部件(车身, 底盘, 轮胎) 构成一辆车, 形成了下面的流程图:  

         从上图可以看出构建一辆车需要依赖于车身, 构建车身又要依赖于底盘, 相同的, 构建底盘也要依赖于轮胎, 这样层层依赖, 最终我们可以类比此过程来 简单用代码实现这个过程:

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);
                }
            }
        }

(4) 这种传统开发的缺陷

         以上过程的轮胎尺寸是固定的, 然而随着对车的需求量的增大, 不同需求的轮胎尺寸孕育而生, 为了满足日益增长的个性化需求, 就需要加工多种不同的轮胎尺寸, 这个时候针对不同的尺寸就需要对上面的代码进行修改了:

public class NewCarUpdateExample {
            public static void main(String[] args) {
                Car car = new Car(20);
                car.run();
            }
            /**
             * 汽⻋对象
             */
            static class Car {
                private Framework framework;
                public Car(int size) {
                    framework = new Framework(size);
                }
                public void run() {
                    // 依赖⻋身
                    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);
                }
            }
        }

        从(3)到(4) 的代码变换过程中可以看出: 当底层的业务逻辑改变之后, 相应的调用链上的代码全部都得修改. 

(5)解决传统开发中的缺陷

        如何解决上面的问题?  我们可以尝试不在每个l类中创建下级类, 如果创建下级类, 就会出现, 下级类发生改变操作的时候, 自己也要跟着修改.

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

        关于解耦:  耦合也就是各个模块之间的关联程度, 关联程度越高, 其耦合就越大, 他们之间相互的影响就越大, 解耦就是指解决代码的耦合性, 好的代码的耦合性是很低的, 也就是代码之间简单地实现了解耦.  

        解耦就好比我们要打造一辆完整的汽车, 如果所有的配件都是自己造的, 那么当客户需求发生改变的时候, 比如轮胎的尺寸不是原来自己造出来的尺寸了, 就需要重新修改尺寸, 如果我们把轮胎外包出去, 那么即使是轮胎尺寸发生改变, 我们只需要向代理厂商下订单就可以了, 我们自身不需要花费力气去修改轮胎尺寸.

        基于上面的思想我们修改代码如下:

public class IocCarExample {
    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.run();
    }
    static class Car {
        private Framework framework;
        public Car(Framework framework) {
            this.framework = framework;
        }
        public void run() {
            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);
        }
    }
}
        代码经过以上调整,⽆论底层类如何变化,整个调⽤链是不⽤做任何改变的,这样就完成了代码之间的解耦,从⽽实现了更加灵活、通⽤的程序设计了.

(6) 对比总结规律

  • 在传统的代码中对象创建顺序是:Car -> Framework -> Bottom -> Tire
  • 改进之后解耦的代码的对象创建顺序是:Tire -> Bottom -> Framework -> Car
        我们发现了⼀个规:通⽤程序的实现代码,类的创建顺序是反的,传统代码是 Car 控制并创建了Framework,Framework 创建并创建了 Bottom,依次往下,⽽改进之后的控制权发⽣的反转,不再是上级对象创建并控制下级对象了,⽽是下级对象把注⼊将当前对象中,下级的控制权不再由上级类控制了,这样即使下级类发⽣任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是 IoC 的实现思想.

(7) 理解IOC 

        回到我们的spring中, 我们刚开始就说过, Spring是包含了多个工具方法的IOC容器 , 这就是对spring的核心总结, 集成了多个工具方法的例子将会在后面的章节进行讲解, 那么我们下面来看看如何理解Spring是ioc容器这句话?

        既然spring是一个ioc容器, 那么我们的重点应该还放在容器二字上面, 也就是他具备两个功能:

  1. 将对象存入到容器
  2. 从容器中取出对象

        也就是说spring最核心的功能就是学习如何将一个对象存入到spring中去, 再从spring容器中取出的过程.

        我们可以类比生产工具的时候, 将对象存储在ioc容器也就相当于将以后所有可能用到的工具全部制作好放到仓库中, 用的时候直接取就行了, 用完再把他放回仓库, 而new对象的操作就相当于每次使用的时候现做, 用完就扔了也不会保存, 下次用的时候还得重新去做, 这就是ioc容器和普通程序开发的区别. 

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



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

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

相关文章

ueditor整合到thinkPHP里

<?phpnamespace app\ueditor\controller;use think\Controller;class Ueditor extends Controller {//首页public function upload(){//header(Access-Control-Allow-Origin: http://www.baidu.com); //设置http://www.baidu.com允许跨域访问//header(Access-Control-Allow…

基于人工大猩猩部队算法优化概率神经网络PNN的分类预测 - 附代码

基于人工大猩猩部队算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于人工大猩猩部队算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于人工大猩猩部队优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&a…

Linux操作系统使用及C高级编程-D11-D13结构体

由一批数据组合而成的结构型数据。组成结构型数据的每个数据称为结构型数据的“成员”&#xff0c;其描述了一块内存空间的大小及解释意义。 语法&#xff1a; struct 结构体名 { 结构体成员列表 }; 下图是struct的定义和使用方法&#xff0c;其中20行这种赋值方式错误&#xf…

c语言上机作业:迭代法求平方根

1.题目 设计一个函数func用迭代法编程求一个数的平方根。平方根的迭代公式为&#xff1a;牛顿迭代法&#xff0c;(要求前后两次迭代值求差的绝对值小于10的-9次方) 2.思路 a.这里要求我们设置一个函数能够完成牛顿迭代法&#xff0c;这里需要使用到函数迭代的知识&#xff0…

时间复杂度与空间复杂度

我们知道算法的效率分为时间效率和空间效率&#xff0c;接下来我们就对这两者进行讨论。 一.时间复杂度. 又被称为时间效率&#xff0c;主要反映一个算法的运行速度。 定义&#xff1a;计算机算法中&#xff0c;算法的时间复杂度是一个函数&#xff0c;它定量描述了该算法的…

excel自定义函数之汉字转为拼音及大写字母

使用场景&#xff1a;想把姓名转化为拼音格式&#xff0c;然后拼音转为大写字母 至于怎么在excel里面自定义函数&#xff0c;自行百度都有&#xff0c;这里简单截图看看。 步骤&#xff1a;文件》选项》自定义功能区》 打开编辑窗口 把下面这段代码粘贴就能实现汉字转化为拼音…

Vulnhub 解决虚拟机网络问题

前言&#xff1a; 有的时候&#xff0c;我们从vulnhub官网下载ovf文件导入到虚拟机后&#xff0c;使用扫描器扫描存活的时候发现扫不到靶机的IP&#xff0c;这是因为虚拟机的网卡配置有问题。我们需要进安全模式修改一些配置。 1. 在虚拟机开机的时候按一下上下键&#xff0c;让…

FreeRTOS内存管理分析

目录 heap_1.c内存管理算法 heap_2.c内存管理算法 heap_3.c内存管理算法 heap_4.c内存管理算法 heap_5.c内存管理算法 内存管理对应用程序和操作系统来说非常重要&#xff0c;而内存对于嵌入式系统来说是寸土寸金的资源&#xff0c;FreeRTOS操作系统将内核与内存管理分开实…

Kubeadm部署Kubernetes Containerd集群

文章目录 概述一、硬件系统二、基础配置设置主机名配置主机名与IP地址解析关闭防火墙与selinux时间同步(ntp)升级系统内核配置内核转发及网桥过滤*安装ipset及ipvsadm关闭SWAP分区 三、Containerd准备Containerd获取下载解压Containerd配置文件生成并修改Containerd启动及开机自…

【项目管理】甘特图(2)——甘特图教程

哈喽啊&#xff0c;你好&#xff0c;我是雷工。 通过上节初步认识了甘特图&#xff0c;本节学习如何一步步创建甘特图&#xff0c;以下为学习笔记。 一、样例展示 下边记录创建甘特图的操作步骤&#xff0c;完成的实际效果如下图所示&#xff1a; 实例图的上端展示项目的重要…

ChatGLM2 大模型微调过程中遇到的一些坑及解决方法(更新中)

1. 模型下载问题 OSError: We couldnt connect to https://huggingface.co to load this file, couldnt find it in the cached files and it looks like bert-base-uncased is not the path to a directory containing a file named config.json. Checkout your internet con…

过了那么多1024节才知道……

各位大佬好啊&#xff0c;相信程序员们都知道1024节&#xff0c;那么咱程序员一般会采取什么样的方式来度过程序员节呢&#xff1f;那我们就继续往下看哦&#xff0c;小编包您满意&#xff01; 先来了解一下历史吧&#xff01;1024节的起源可以追溯到2009年&#xff0c;当时俄…

windows排除扫描文件夹

搜索防火墙和网络保护 点击病毒和威胁防护 往下拉&#xff0c;找到排除项 添加排除项

【在飞书捷径中用HTTP请求】

在飞书捷径的请求体中的变量&#xff0c;注意外面要有个双引号。

转型做视频了,博客就是稿子,继续坚持写博客,同时发布视频,能写博客说明思路清晰了,能再讲明白,理解就更透彻了,紧跟上时代发展。

1&#xff0c;今天特别记录下&#xff0c;B站给开通了《合集》功能 最近使用视频制作了几个视频。播放量还不错&#xff0c;最好的已经到了 2.6K了。 然后粉丝也涨到了 200个。 添加链接描述 紧跟时代&#xff1a;从写博客到录视频&#xff0c;粉丝大涨&#xff0c;突破200个&…

扩散模型实战(十一):剖析Stable Diffusion Pipeline各个组件

推荐阅读列表&#xff1a; 扩散模型实战&#xff08;一&#xff09;&#xff1a;基本原理介绍 扩散模型实战&#xff08;二&#xff09;&#xff1a;扩散模型的发展 扩散模型实战&#xff08;三&#xff09;&#xff1a;扩散模型的应用 扩散模型实战&#xff08;四&#xff…

Linux下安装go

正式环境&#xff1a; 1、找到linux 版本go包 &#xff08;Downloads - The Go Programming Language&#xff09; 2、下载 wget https://dl.google.com/go/go1.17.5.linux-amd64.tar.gz3、解压到/usr/local &#xff08;官方推荐&#xff09; tar -C /usr/local -zxvf go1…

火狐挂代理访问问题Software is preventing Firefox from safely connecting to this site

1、报错 Software is preventing Firefox from safely connecting to this site2、解决步骤 火狐浏览器访问http://burp&#xff0c;右上角有下载按钮下载下来证书文件 在 Firefox 中设置证书颁发机构 (CA) 验证

小程序中打印机纸张都支持哪些尺寸?

在小程序中添加打印机功能是一项非常实用的功能&#xff0c;它可以让用户方便地将小程序中的内容打印出来。然而&#xff0c;当用户想要打印内容时&#xff0c;他们可能会关心打印纸张支持哪些尺寸。打印机分为四种打印机&#xff1a;小票、标签、发货单和电子面单。下面具体介…

数字化转型导师坚鹏:数字化时代银行网点厅堂营销5大关键点分析

数字化时代银行网点厅堂营销需要抓住以下5大关键点&#xff1a; 1、精准识别客户&#xff1a;在数字化时代&#xff0c;银行网点厅堂营销的关键在于精准识别客户。通过利用大数据和人工智能技术&#xff0c;银行可以分析客户的行为和需求&#xff0c;从而更好地了解客户&#…