• JavaEE进阶学习:Spring核心和设计思想


    Spring 是什么

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

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

    1.什么是容器

    容器是用来容纳某种物品的(基本)装置。

    我们学过的容器:
    List/Map -> 数据存储容器
    Tomcat -> Web 容器

    2.什么是 IoC

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

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

    控制(权)反转
    对象的生命周期是由当前代码 / 程序员来控制的,当用了 Spring 时,就会由 Spring (Spring 容器)控制

    Ioc 的优势
    可以实现解耦(松耦合)

    我们举 car 的例子来解释:
    在这里插入图片描述

    构建一辆车(Car Class),然而车需要依赖车身(FrameWork Class),而车身需要依赖底盘(BottomClass),而底盘需要依赖轮胎(Tire Class)

    package old;
    
    /**
     * @projectName: test-2023-11-13
     * @package: old
     * @className: car
     * @author: 王嘉辉
     * @description:
     * @date: 2023/11/13 17:04
     * @version: 1.0
     */
    
    /**
     * 传统的开发
     */
    public class Car {
    
        //车身
        private FrameWork framework;
    
        public Car() {
            this.framework = new FrameWork();
        }
    
        public void init() {
            System.out.println("执行了 Car init 方法");
            framework.init();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    package old;
    
    /**
     * @projectName: test-2023-11-13
     * @package: old
     * @className: FrameWork
     * @author: 王嘉辉
     * @description:
     * @date: 2023/11/13 18:57
     * @version: 1.0
     */
    public class FrameWork {
        private Bottom bottom;
    
        public FrameWork() {
            this.bottom = new Bottom();
        }
    
        public void init() {
            System.out.println("执行了 FrameWork init 方法");
            bottom.init();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    package old;
    
    /**
     * @projectName: test-2023-11-13
     * @package: old
     * @className: Bottom
     * @author: 王嘉辉
     * @description:
     * @date: 2023/11/13 19:00
     * @version: 1.0
     */
    public class Bottom {
    
        private Tire tire;
    
        public Bottom() {
            this.tire = new Tire();
        }
    
        public void init() {
            System.out.println("执行了 Bottom init 方法");
            tire.init();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    package old;
    
    /**
     * @projectName: test-2023-11-13
     * @package: old
     * @className: Tire
     * @author: 王嘉辉
     * @description:
     * @date: 2023/11/13 19:01
     * @version: 1.0
     */
    public class Tire {
        private int size = 15;
        public void init() {
            System.out.println("执行了Tire init. Size: " + size);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    package old;
    
    /**
     * @projectName: test-2023-11-13
     * @package: old
     * @className: Test
     * @author: 王嘉辉
     * @description:
     * @date: 2023/11/13 19:04
     * @version: 1.0
     */
    public class Test {
        public static void main(String[] args) {
            Car car = new Car();
            car.init();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    我们需要加工多种尺寸的轮胎,就要对上述代码进行修改

    package old;
    
    /**
     * @projectName: test-2023-11-13
     * @package: old
     * @className: car
     * @author: 王嘉辉
     * @description:
     * @date: 2023/11/13 17:04
     * @version: 1.0
     */
    
    /**
     * 传统的开发
     */
    public class Car {
    
        //车身
        private FrameWork framework;
    
        public Car(int size) {
            this.framework = new FrameWork(size);
        }
    
        public void init() {
            System.out.println("执行了 Car init 方法");
            framework.init();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    package old;
    
    /**
     * @projectName: test-2023-11-13
     * @package: old
     * @className: FrameWork
     * @author: 王嘉辉
     * @description:
     * @date: 2023/11/13 18:57
     * @version: 1.0
     */
    public class FrameWork {
        private Bottom bottom;
    
        public FrameWork(int size) {
            this.bottom = new Bottom(size);
        }
    
        public void init() {
            System.out.println("执行了 FrameWork init 方法");
            bottom.init();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    package old;
    
    /**
     * @projectName: test-2023-11-13
     * @package: old
     * @className: Bottom
     * @author: 王嘉辉
     * @description:
     * @date: 2023/11/13 19:00
     * @version: 1.0
     */
    public class Bottom {
    
        private Tire tire;
    
        public Bottom(int size) {
            this.tire = new Tire(size);
        }
    
        public void init() {
            System.out.println("执行了 Bottom init 方法");
            tire.init();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    package old;
    
    /**
     * @projectName: test-2023-11-13
     * @package: old
     * @className: Tire
     * @author: 王嘉辉
     * @description:
     * @date: 2023/11/13 19:01
     * @version: 1.0
     */
    public class Tire {
        private int size = 15;
    
        public Tire(int size) {
            this.size = size;
        }
        public void init() {
            System.out.println("执行了Tire init. Size: " + size);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    package old;
    
    /**
     * @projectName: test-2023-11-13
     * @package: old
     * @className: Test
     * @author: 王嘉辉
     * @description:
     * @date: 2023/11/13 19:04
     * @version: 1.0
     */
    public class Test {
        public static void main(String[] args) {
            Car car = new Car(20);
            car.init();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    当最底层代码改动之后,整个调用链上的所有代码都需要修改。

    我们使用IoC解耦
    在这里插入图片描述

    package ioc;
    
    
    
    
    /**
     * @projectName: test-2023-11-13
     * @package: ioc
     * @className: Car
     * @author: 王嘉辉
     * @description:
     * @date: 2023/11/13 19:56
     * @version: 1.0
     */
    public class Car {
        private FrameWork frameWork;
        public Car(FrameWork frameWork) {
            this.frameWork = frameWork;
            //frameWork = new FrameWork();
        }
    
        public void init() {
            System.out.println("Car init");
            frameWork.init();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    package ioc;
    
    
    
    
    /**
     * @projectName: test-2023-11-13
     * @package: ioc
     * @className: FrameWork
     * @author: 王嘉辉
     * @description:
     * @date: 2023/11/13 20:00
     * @version: 1.0
     */
    public class FrameWork {
        private Bottom bottom;
    
        public FrameWork(Bottom bottom) {
            this.bottom = bottom;
        }
    
        public void init() {
            System.out.println("FrameWork init ");
            bottom.init();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    package ioc;
    
    
    
    /**
     * @projectName: test-2023-11-13
     * @package: ioc
     * @className: Bottom
     * @author: 王嘉辉
     * @description:
     * @date: 2023/11/13 20:01
     * @version: 1.0
     */
    public class Bottom {
        private Tire tire;
    
        public Bottom(Tire tire) {
            this.tire = tire;
        }
    
        public void init() {
            System.out.println("Bottom init");
            tire.init();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    package ioc;
    
    /**
     * @projectName: test-2023-11-13
     * @package: ioc
     * @className: Tire
     * @author: 王嘉辉
     * @description:
     * @date: 2023/11/13 20:02
     * @version: 1.0
     */
    public class Tire {
        private int size = 15;
    
        public Tire() {}
        public void init() {
            System.out.println("Tire init. Size: " + size);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    package ioc;
    
    /**
     * @projectName: test-2023-11-13
     * @package: ioc
     * @className: Test
     * @author: 王嘉辉
     * @description:
     * @date: 2023/11/13 20:03
     * @version: 1.0
     */
    
    
    
    /**
     * 模拟Ioc
     */
    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();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

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

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

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

    3.Spring IoC

    Spring 是包含了多个工具方法的 IoC 容器,这就是对Spring 最核心的总结。

    Spring 是⼀个 IoC(控制反转)容器,重点还在“容器”⼆字上,那么它就具备两个最基础的功能:

    • 将对象存入到容器;
    • 从容器中取出对象。

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

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

    4.DI 概念说明

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

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

    IoC 是“目标”也是⼀种思想,而目标和思想只是⼀种指导原则,最终还是要有可行的落地方案,而 DI就属于具体的实现。

  • 相关阅读:
    背包理论之01背包
    7×24无人值守直播推流软件开发实战,一文为你揭开视频推流的底层原理(附源码)
    RK3568 + YT 9215交换机芯片,MAC TO MAC 调试记录
    基于Java和MySql的产业信息管理系统的设计与实现 毕业设计-附源码260839
    牛客刷题系列之进阶版(搜索旋转排序数组,链表内指定区间反转)
    elementui实现图片和表单信息同时上传
    git dep preparation failed 报错
    Linux输出转换命令 xargs
    shell脚本编程
    LeetCode 面试题 08.04. 幂集
  • 原文地址:https://blog.csdn.net/m0_66030479/article/details/134381217