1. Spring 核心与设计思想

目录

[1. Spring 是什么?](#1. Spring 是什么?)

[1.1 什么是容器?](#1.1 什么是容器?)

[1.2 什么是 Ioc ?](#1.2 什么是 Ioc ?)

[1.2.1 传统程序开发](#1.2.1 传统程序开发)

[1.2.2 解决传统开发的缺陷](#1.2.2 解决传统开发的缺陷)

[1.2.3 控制反转式程序开发](#1.2.3 控制反转式程序开发)

[1.2.4 IoC 的实现思想(重点)](#1.2.4 IoC 的实现思想(重点))

[1.3 理解 Spring Ioc](#1.3 理解 Spring Ioc)

[1.4 DI 概念说明](#1.4 DI 概念说明)


1. Spring 是什么?

Spring 指的是 Spring Framework (spring 框架),它是一个开源框架,有着活跃而庞大的社区,这就是它之所以能长久不衰的原因。

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

1.1 什么是容器?

容器是用来容纳某种物品的装置。

  • List/Map -> 数据存储容器
  • Tomcat -> Web容器

1.2 什么是 Ioc ?

IoC = Inversion of Control 即 控制反转,也就是说 Spring 是一个"控制反转"的容器。

1.2.1 传统程序开发

是通过一层一层的依赖实现的。比如我们要构建一辆车,需要依赖车身,车身进而需要依赖底盘,底盘又需要依赖轮胎。因此一般的实现代码如下:

在 NewCarUpateExample 类中:

java 复制代码
public class NewCarUpateExample {
    public static void main(String[] args) {
        Car car = new Car();
        car.init();
    }
}

首先,我们先创建一个汽车对象:

java 复制代码
/**
 * 汽车对象
 */
public class Car {
    public void init(){
        // 依赖车身
        Framework framework = new Framework();
        framework.init();
    }
}

由于汽车对象需要依赖车身,因此我们创建一个车身类:

java 复制代码
/**
 * 车身类
 */
public class Framework {
    public void init(){
        // 依赖底盘
        Bottom bottom = new Bottom();
        bottom.init();
    }
}

又因为车身依赖于底盘,因此创建底盘类:

java 复制代码
/**
 * 底盘类
 */
public class Bottom {
    public void init(){
        // 依赖轮胎
        Tire tire = new Tire();
        tire.init();
    }
}

最后,因为底盘依赖于轮胎,因此创建轮胎类:

java 复制代码
/**
 * 轮胎类
 */
public class Tire {
    // 轮胎尺寸
    private int size = 30;

    public void init(){
        System.out.println("轮胎尺寸" + size);
    }
}

在以上程序中,轮胎的尺寸是固定的,但是实际中根据各种需求,轮胎的尺寸也会发生变化,因此修改代码如下:

在 NewCarUpateExample 类中:

java 复制代码
public class NewCarUpateExample {
    public static void main(String[] args) {
        Car car = new Car(20);
        car.run();
    }
}
java 复制代码
/**
 * 汽车对象
 */
public class Car {
    private Framework framework;

    public Car(int size){
        framework = new Framework(size);
    }
    public void run(){
        // 依赖车身
        framework.init();
    }
}
java 复制代码
/**
 * 车身类
 */
public class Framework {
    private Bottom bottom;

    public Framework(int size){
        bottom = new Bottom(size);
    }
    public void init(){
        // 依赖底盘
        bottom.init();
    }
}
java 复制代码
/**
 * 底盘类
 */
public class Bottom {
    private Tire tire;
    public Bottom(int size){
        tire = new Tire(size);
    }
    public void init(){
        // 依赖轮胎
        tire.init();
    }
}
java 复制代码
/**
 * 轮胎类
 */
public class Tire {
    // 轮胎尺寸
    private int size;
    public Tire(int size){
        this.size = size;
    }
    public void init(){
        System.out.println("轮胎尺寸" + size);
    }
}

从以上代码可以看出:当最底层的代码修改后,其他层的代码均需要进行修改。

1.2.2 解决传统开发的缺陷

如何解决代码之间的耦合性过高的问题呢?

我们只需要将原来自己创建的下级类,改为传递的方式(也就是注入 ),因为我们不需要在当前类中创建下级类,所以下级类发生变化时,当前类本身就无需再进行修改,这样就完成了程序的解耦

1.2.3 控制反转式程序开发

接下来,在上述程序的基础上,我们将创建子类的方式改为注入传递的方式。

java 复制代码
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();
    }
}
java 复制代码
/**
 * 汽车对象
 */
public class Car {
    private Framework framework;

    public Car(Framework framework){
        this.framework = framework;
    }
    public void run(){
        // 依赖车身
        framework.init();
    }
}
java 复制代码
/**
 * 车身类
 */
public class Framework {
    private Bottom bottom;

    public Framework(Bottom bottom){
        this.bottom = bottom;
    }
    public void init(){
        // 依赖底盘
        bottom.init();
    }
}
java 复制代码
/**
 * 底盘类
 */
public class Bottom {
    private Tire tire;
    public Bottom(Tire tire){
        this.tire = tire;
    }
    public void init(){
        // 依赖轮胎
        tire.init();
    }
}
java 复制代码
/**
 * 轮胎类
 */
public class Tire {
    // 轮胎尺寸
    private int size;
    public Tire(int size){
        this.size = size;
    }
    public void init(){
        System.out.println("轮胎尺寸" + size);
    }
}

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

1.2.4 IoC 的实现思想(重点)

在传统代码中对象创建的规律是:Car -> Framework -> Bottom -> TIre

改进之后解耦的代码的对象创建顺序是:TIre -> Bottom -> Framework -> Car

改进之后的控制权发生的反转,不再是上级对象创建并控制下级对象了,而是把下级对象注入当前对象中,下级的控制权不再由上级类控制了,这样即使下级类发⽣任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是 IoC 的实现思想

(对于依赖对象的管理的控制权反转,通过 Spring 来管理对象的生命周期。不是所有的对象都交给 Spring 管理,需要程序来告诉 Spring 管理哪些对象)。

1.3 理解 Spring Ioc

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

能:

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

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

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

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

1.4 DI 概念说明

DI 是 Dependency Injection 的缩写,即 依赖注入

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

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

相关推荐
wrx繁星点点3 分钟前
事务的四大特性(ACID)
java·开发语言·数据库
IT学长编程10 分钟前
计算机毕业设计 Java酷听音乐系统的设计与实现 Java实战项目 附源码+文档+视频讲解
java·spring boot·毕业设计·课程设计·毕业论文·音乐系统·计算机毕业设计选题
IT学长编程27 分钟前
计算机毕业设计 基于协同过滤算法的个性化音乐推荐系统的设计与实现 Java实战项目 附源码+文档+视频讲解
java·spring boot·毕业设计·毕业论文·协同过滤算法·计算机毕业设计选题·个性化音乐推荐系统
小小娥子32 分钟前
Redis的基础认识与在ubuntu上的安装教程
java·数据库·redis·缓存
几何心凉40 分钟前
已解决:org.springframework.web.HttpMediaTypeNotAcceptableException
java
华农第一蒟蒻42 分钟前
Java中JWT(JSON Web Token)的运用
java·前端·spring boot·json·token
两点王爷44 分钟前
使用WebClient 快速发起请求(不使用WebClientUtils工具类)
java·网络
计算机学姐1 小时前
基于SpringBoot+Vue的高校运动会管理系统
java·vue.js·spring boot·后端·mysql·intellij-idea·mybatis
平凡的小码农1 小时前
JAVA实现大写金额转小写金额
java·开发语言
一直在进步的派大星1 小时前
Docker 从安装到实战
java·运维·docker·微服务·容器