初识Spring

目录

[1.Spring 基础](#1.Spring 基础)

2.传统程序开发

3.IoC程序开发(解耦)

4.DI

[4.1 IoC 和 DI 有什么区别](#4.1 IoC 和 DI 有什么区别)


1.Spring 基础

Spring 指的是 Spring Framework(Spring 框架),它是⼀个开源框架,有着活跃⽽庞⼤的社区,这就是它之所以能⻓久不衰的原因。Spring ⽀持⼴泛的应⽤场景,它可以让 Java 企业级的应⽤程序开发起来更简单。

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

容器:⽤来容纳某种物品的(基本)装置(例如:List/Map ---> 数据存储容器、Tomcat ----> Web 容器)

IoC:IoC = Inversion of Control 翻译成中⽂是"控制反转"的意思,也就是说 Spring 是⼀个"控制反转"的容器

控制(权)反转:对象的生命周期,不是由程序员(或当前代码片段)来控制,而是由 Spring(Spring 容器/ IoC容器)来控制

IoC最大的优点:可以实现解耦(松耦合)

2.传统程序开发

假如,我们现在构建⼀辆"⻋"的程序,我们的实现思路是这样的:

java 复制代码
/**
 * 传统开发:汽车对象
 */
public class Car {

    private Framework framework;//依赖车声,建立车身

    //在构造方法中 new
    public Car() {
        this.framework = new Framework();
    }

    public void init() {
        //依赖车身
        System.out.println("执行了 init 方法");
        framework.init();
    }
}
java 复制代码
/**
 * 车身类
 */
public class Framework {
    private Bottom bottom;
    public Framework() {
        this.bottom = new Bottom();
    }
    public void init() {
        //依赖底盘
        System.out.println("执行了 Framework init 方法");
        bottom.init();
    }
}
java 复制代码
/**
 * 底盘类
 */
public class Bottom {
    private Tire tire;
    public Bottom() {
        this.tire = new Tire();
    }

    public void init() {
        //依赖轮胎
        System.out.println("执行了 Bottom init 方法");
        tire.init();
    }
}
java 复制代码
/**
 * 轮胎类
 */
public class Tire {
    private  int size = 15;
    public void init() {
        System.out.println("执行了 Tire init,Size:"+ size);
    }
}

这个时候我们执行这段代码:

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

上述代码中轮胎的尺寸是固定的,然而随着对的车的需求量越来越⼤,个性化需求也会越来越多,这 时候我们就需要加工多种尺⼨的轮胎,那这个时候就要对上面的程序进行修改:

注意每一类中size的改动

java 复制代码
/**
 * 传统开发:汽车对象
 */
public class Car {

    private Framework framework;

    public Car(int size) {
        this.framework = new Framework(size);
    }

    public void init() {
        //依赖车身
        System.out.println("执行了 init 方法");
        framework.init();
    }
}

/**
 * 车身类
 */
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();
    }
}

/**
 * 底盘类
 */
public class Bottom {
    private Tire tire;
    
    //Botton 中没有size参数,继续让别人传参数
    public Bottom(int size) {
        this.tire = new Tire(size);
    }

    public void init() {
        //依赖轮胎
        System.out.println("执行了 Bottom init 方法");
        tire.init();
    }
}

/**
 * 轮胎类
 */
public class Tire {
    private  int size = 15;

    //传递 size 参数
    public Tire(int size) {
        this.size = size;
    }

    public void init() {
        System.out.println("执行了 Tire init,Size:"+ size);
    }
}

public class Test {
    public static void main(String[] args) {
        Car car = new Car(20);
        car.init();
    }
}

这个时候我们发现,虽然我们可以改变轮胎的尺寸,但是最底层代码改动之后,整个调用链上的所有代码都需要修改------耦合性问题

需求指挥越来越多,改动的也会越来越多,这个时候我们就可以使用 IoC 进行解耦

3.IoC程序开发(解耦)

java 复制代码
/**
 * IoC:汽车对象
 */
public class Car {
    private Framework framework;

    //初始化(不是用传统开发):让框架传入(不管咋样传入),声明使用Framework
    //如果是一个IoC框架,运行代码,会拿到当前框架中的Framework 赋值到当前变量中就会有 framework
    public Car(Framework framework) {
        this.framework = framework;
    }

    public void init() {
        System.out.println("Car init");
        framework.init();
    }
}

public class Framework {
    private Bottom bottom;
    public Framework(Bottom bottom) {
        this.bottom = bottom;
    }
    public void init() {
        System.out.println("Framework init");
        bottom.init();
    }
}

public class Bottom {
    private Tire tire;
    public Bottom(Tire tire) {
        this.tire = tire;
    }
    public void init() {
        System.out.println("Bottom init");
        tire.init();
    }
}

public class Tire {
    private int size = 15;
    public Tire() {

    }
    public void init() {
        System.out.println("Tire init, Size:" + size);
    }
}

/**
 * 模拟 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();
    }
}

需要改尺寸只需要修改 Tire 类中的尺寸:

java 复制代码
public class Tire {
    private int size = 15;
    public Tire(int size) {
        this.size = size;
    }
    public void init() {
        System.out.println("Tire init, Size:" + size);
    }
}

这个时候只需要改 IoC 容器(Spring 框架 )即可(IoC 与用户没有关系),Spring 框架会自动设置参数

java 复制代码
public class Test {
    private Tire tire;
    private Bottom bottom;
    private Framework framework;
    private Car car;

    public Test() {
        this.tire = new Tire(20);
        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,Framework 创建并创建了 Bottom,依次往下,⽽改进之后的控制权发⽣的反转,不再是上级对象创建并控制下级对象了,⽽是下级对象把注⼊将当前对象中,下级的控制权不再由上级类控制了,这样即使下级类发⽣任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是 IoC 的实现思想。

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

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

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

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

4.DI

DI 是 Dependency Injection 的缩写,翻译成中文是"依赖注入"的意思:指的是由 IoC 容器在运行期间,动态的将依赖对象获取到的过程

java 复制代码
public class Car {
    private Framework framework;

    public Car(Framework framework) {
        this.framework = framework;
    }

    public void init() {
        System.out.println("Car init");
        framework.init();
    }
}

在运行 Car 时,动态的将 Framework 拿到当前类中的过程就叫做 依赖注入 (在运行类的时候,需要有一个依赖类,依赖类就会从容器中动态的查询出来,赋值给变量,就可以直接使用这个方法)

所以,依赖注⼊(DI)和控制反转(IoC)是从不同的⻆度的描述的同⼀件事情,就是指通过引⼊ IoC 容器,利⽤依赖关系注⼊的⽅式,实现对象之间的解耦;

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

比如说我今天吃⼀顿美餐,那么"美餐"是目标(是 IoC),但最后我是吃火锅还是烧烤?这就是具体的实现,就是DI

4.1 IoC 和 DI 有什么区别

IoC 和 DI 都是 Spring 框架中的核心概念,它们的区别在于:

  • IoC(Inverse of Control,控制反转):它是一种思想,主要解决程序设计中的对象依赖关系管理问题。在 IoC 思想中,对象的创建权反转给第三方容器,由容器进行对象的创建及依赖关系的管理。
  • DI(Dependency Injection,依赖注入):它是 IoC 思想的具体实现方式之一,用于实现 IoC。在 Spring 中,依赖注入是指:在对象创建时,由容器自动将依赖对象注入到需要依赖的对象中。

简单来说,它们的关系是:

  • IoC 是一种思想、理念,定义了对象创建和依赖关系处理的方式。
  • DI 是 IoC 思想的具体实现方式之一,实际提供对象依赖关系的注入功能。

所以 IoC 是更基础和广义的概念,DI 可以说是 IoC 的一种实现手段。大多数情况下,我们提到 IoC 的时候,其实意味着 DI,因为 DI 已经是 IoC 最常见和广泛使用的实现方式了。

例如在 Spring 框架中:

  • IoC 体现为 Spring 容器承担了对象创建及依赖关系管理的控制权。
  • DI 体现为 Spring 容器通过构造方法注入、Setter 方法注入等方式,将依赖对象注入到需要依赖的对象中。

所以综上,IoC 和 DI 之间的关系可以这样理解:

  • IoC 是理论,DI 是实践。
  • IoC 是思想,DI 是手段。
  • IoC 是整体,DI 是部分。
相关推荐
陈平安Java and C5 小时前
MyBatisPlus
java
秋野酱5 小时前
如何在 Spring Boot 中实现自定义属性
java·数据库·spring boot
安的列斯凯奇6 小时前
SpringBoot篇 单元测试 理论篇
spring boot·后端·单元测试
Bunny02126 小时前
SpringMVC笔记
java·redis·笔记
blammmp6 小时前
Java EE 进阶:Spring MVC(1)
spring·java-ee·mvc
架构文摘JGWZ6 小时前
FastJson很快,有什么用?
后端·学习
BinaryBardC6 小时前
Swift语言的网络编程
开发语言·后端·golang
feng_blog66886 小时前
【docker-1】快速入门docker
java·docker·eureka
邓熙榆6 小时前
Haskell语言的正则表达式
开发语言·后端·golang
枫叶落雨2228 小时前
04JavaWeb——Maven-SpringBootWeb入门
java·maven