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)

java 复制代码
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();
    }
}
java 复制代码
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();
    }
}
java 复制代码
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();
    }
}
java 复制代码
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);
    }
}
java 复制代码
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();
    }
}

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

java 复制代码
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();
    }
}
java 复制代码
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();
    }
}
java 复制代码
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();
    }
}
java 复制代码
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);
    }
}
java 复制代码
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();
    }
}

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

我们使用IoC解耦

java 复制代码
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();
    }
}
java 复制代码
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();
    }
}
java 复制代码
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();
    }
}
java 复制代码
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);
    }
}
java 复制代码
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();
    }
}

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

在传统的代码中对象创建顺序是: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就属于具体的实现。

相关推荐
Wx-bishekaifayuan17 分钟前
django电商易购系统-计算机设计毕业源码61059
java·spring boot·spring·spring cloud·django·sqlite·guava
customer0821 分钟前
【开源免费】基于SpringBoot+Vue.JS周边产品销售网站(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·java-ee·开源
@小博的博客35 分钟前
C++初阶学习第十弹——深入讲解vector的迭代器失效
数据结构·c++·学习
小白冲鸭1 小时前
【报错解决】使用@SpringJunitConfig时报空指针异常
spring·java后端开发
南宫生1 小时前
贪心算法习题其四【力扣】【算法学习day.21】
学习·算法·leetcode·链表·贪心算法
LuckyLay2 小时前
Spring学习笔记_27——@EnableLoadTimeWeaving
java·spring boot·spring
Stringzhua2 小时前
【SpringCloud】Kafka消息中间件
spring·spring cloud·kafka
懒惰才能让科技进步2 小时前
从零学习大模型(十二)-----基于梯度的重要性剪枝(Gradient-based Pruning)
人工智能·深度学习·学习·算法·chatgpt·transformer·剪枝
love_and_hope2 小时前
Pytorch学习--神经网络--搭建小实战(手撕CIFAR 10 model structure)和 Sequential 的使用
人工智能·pytorch·python·深度学习·学习
Chef_Chen2 小时前
从0开始学习机器学习--Day14--如何优化神经网络的代价函数
神经网络·学习·机器学习