SpringIoC & DI (1):IOC介绍 & Spring IoC使用 & DI

SpringIoC & DI (1):IOC介绍 & Spring IoC使用 & DI

文章目录

  • [SpringIoC & DI (1):IOC介绍 & Spring IoC使用 & DI](#SpringIoC & DI (1):IOC介绍 & Spring IoC使用 & DI)
  • [1. 什么是 Spring:](#1. 什么是 Spring:)
  • [2. IOC设计思想:](#2. IOC设计思想:)
  • [3. DI(依赖注入):](#3. DI(依赖注入):)
  • [4. IoC 结合 DI:](#4. IoC 结合 DI:)
  • [5. Spring中 IoC 结合 DI使用:](#5. Spring中 IoC 结合 DI使用:)
    • [1. 不使用 @Component](#1. 不使用 @Component)
    • [2. 不使用 @Autowired](#2. 不使用 @Autowired)
  • 总结:

观前提醒

这篇博客的代码,是比较简单的。

你自己可以创建类,使用注解,调用对象,就能够看见效果。

1. 什么是 Spring:

之前我们说,Spring 这个词语,能够表示这些意思意思:

  1. Spring家族
  2. Spring Framework,也就做 SpringCore(最原始的 Spring框架)

现在,讲到 IoC,我们可以说,Spring:Spring 是包含了众多⼯具⽅法的 IoC 容器。

Spring核心思想

IoC(Inversion of Control,控制反转)是 Spring 框架的核心思想之一,也是面试中经常被考察的重点内容!

另一个核心思想是 AOP(Aspect-Oriented Programming,面向切面编程),同样在面试中频频出现,常与 IoC 一起作为 Spring 的两大基石进行考查。

容器,好理解,是用来装东西的。

Spring容器,装的是 Java对象。

IoC指的是什么?

IoC的全称是:Inversion of Control (控制反转)

也就是说 Spring 是⼀个"控制反转"的容器。

什么叫做控制反转?

这里指的是:对象的控制权发生了反转。

对象的控制权:

之前:谁使用,控制权就在谁的手上(Test方法,调用了一个 A对象,这个 A对象的控制前就在 Test方法手上)

使用Spring (IoC容器),现在:Spring来控制对象。

控制反转这种思想 ,生活中有个例子:智能驾驶

没使用智驾,是人在控制车。

使用智驾,是智驾系统在开车。

2. IOC设计思想:

我们以造车为例子,讲解什么叫做 IoC的设计思想。

传统方式(自己造车):

使用程序来设计:

代码:

java 复制代码
package org.example.springioc_demo_20251022.v1;


// 轮胎
public class Tire {
    private int size;

    public Tire(int size) {
        this.size = size;
        System.out.println("tire init,size is:" + size);
    }
}


----------------------------------
package org.example.springioc_demo_20251022.v1;

//底盘
public class Bottom {
    private Tire tire;

    public Bottom(int size) {
        this.tire = new Tire(size);
        System.out.println("bottom init...");
    }
} 
----------------------------------
package org.example.springioc_demo_20251022.v1;

//车身
public class Framework {
    private Bottom bottom;

    public Framework(int size) {
        this.bottom = new Bottom(size);
        System.out.println("framework init....");
    }
}

----------------------------------
package org.example.springioc_demo_20251022.v1;

//车
public class Car {
    private Framework framework;

    public Car(int size) {
        this.framework = new Framework(size);
        System.out.println("car init...");
    }

    public void run() {
        System.out.println("car start run...");
    }
}
---------------------------------
package org.example.springioc_demo_20251022.v1;


public class Main {
    public static void main(String[] args) {
//        客户提要求,要我造什么尺寸的轮胎的车。
        Car car = new Car(17);

        car.run();
    }
}

这是传统的方式造车,自己造车。

但是,如果客户要求轮胎的颜色,尺寸,我们需要从头开始,一个一个去通知造车身,底盘,轮胎的部门。

根据轮⼦的尺寸设计的底盘,轮胎尺寸变了,底盘就要重新设计,

因为我们是根据底盘设计的车⾝,底盘重新设计,车身就要重新设计,

汽车设计也得改, 也就是整个设计⼏乎都得改。

从以上代码可以看出,以上程序的问题是:当最底层代码改动之后,整个调用链上的所有代码都需要修改
程序的耦合度非常高(修改一处代码,影响其他处的代码修改)

所以,我们采用 IoC 的设计思想,外包出去,让别的公司,来帮我们造轮胎,底盘,车身。

最后,我们只需要拼接好这些零件,把车组装出来就行。

IoC设计思想(公司外包):


代码:

java 复制代码
package org.example.springioc_demo_20251022.v2;

public class Tire {
    private int size;
    private String color;

    public Tire(int size, String color) {
        this.size = size;
        this.color = color;
        System.out.println("tire init,size is:" + size);
    }
}


----------------------------------
package org.example.springioc_demo_20251022.v2;


public class Bottom {
    private Tire tire;

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

----------------------------------
package org.example.springioc_demo_20251022.v2;

//车身
public class Framework {
    private Bottom bottom;

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


----------------------------------
package org.example.springioc_demo_20251022.v2;


public class Car {
    private Framework framework;

    public Car(Framework framework) {
        this.framework = framework;
        System.out.println("car init...");
    }

    public void run() {
        System.out.println("car start run...");
    }
}

---------------------------------
package org.example.springioc_demo_20251022.v2;


public class Main {
    public static void main(String[] args) {
//        零件外包:

//        客户更换轮胎尺寸,颜色,直接和造轮胎的说要求
//        轮胎设计好之后,直接拿到轮胎
        Tire tire = new Tire(17,"red");

//        根据轮胎要求,造底盘的公司设计好底盘后,拿到底盘。
        Bottom bottom = new Bottom(tire);

//        根据底盘要求,造车身的公司设计好车身后,拿到车身。
        Framework framework = new Framework(bottom);

//        把零件组装起来,把车造好
        Car car = new Car(framework);

        car.run();
    }
}

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

后续,如果要重新设计轮胎尺寸,颜色,只需要和 造轮胎 的公司说就行,造底盘的会自动根据轮胎要求,设计不同的底盘。

外包之后,不需要造车的这个公司,一个一个去重新设计这么麻烦了。

这就是 耦合度 很低的例子。

苹果手机也是,富士康是组装苹果手机的公司,从别的厂家拿来 CPU(台积电代工),屏幕(三星代工),电池,扬声器...... 这些零件,富士康组装即可。

至于修改,只需要通知设计对应零件的那一家公司,大大了 设计手机 的耦合度。

这就是 IoC 的设计思想。

IoC优势:

在传统的代码中对象创建顺序是:Car -> Framework -> Bottom -> Tire

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

传统代码是 Car 控制并创建了 Framework,Framework 创建并创建了 Bottom,依次往下

而改进之后的控制权发生的反转,不再是使用方对象创建并控制依赖对象了,而是把 依赖对象注入将当前对象 中,依赖对象的控制权不再由当前类控制了

这样的话, 即使依赖类发⽣任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是 IoC 的实现思想。

3. DI(依赖注入):

DI(Dependency Injection,依赖注入)

在上述代码中,通过构造函数的方式,将依赖对象注入到需要使用该依赖的对象中。

4. IoC 结合 DI:

IoC(Inversion of Control,控制反转)是一种设计思想,也是一种目标。

思想本身只提供指导原则,要真正落地,还需要具体的实现方式。

而 DI(Dependency Injection,依赖注入)正是实现 IoC 的一种常见且有效的具体手段。因此,可以说:DI 是 IoC 的一种实现方式

5. Spring中 IoC 结合 DI使用:

IoC的设计思想,就是想让别人帮我们创造对象(外包),Spring提供了注解:@Component

被 @Component 标记的类,会交给 Spring进行管理,Spring会自动在 IoC容器中,创建这个类的对象。

这个对象,就是由 Spring 进行控制的了。

这就是 Spring(IoC容器),进行对象管理的方式了。

既然这个类创建了,就得拿来用。

DI,就是我们从 IoC容器 中,拿取这些自动创建的类的一种手段,Spring提供了注解:@Autowired

画个图片理解就是:

1. 不使用 @Component

如果我们不使用 @Component 管理某一个类,而我们又使用了 @Autowired,往其他类中,注入这个类的对象,会出现这样的错误:

Bean

Bean,在 Spring 中,表示 对象。

2. 不使用 @Autowired

我们不使用 @Autowired 注入 IoC容器中的某个对象给 变量,会出现这样的错误:

总结:

我们学了两个注解:

  1. @Component:表示将这个类自动创建对象,这个对象,放到 SpringIoC容器中,交给 Spring 管理。(存放对象到容器中)
  2. @Autowired:表示从 SpringIoC容器中,获取某一个对象,并赋值给一个 引用变量。(从容器中取对象)

@Autowired 必须要和 任意一个能够让 Spring管理对象的注解(例如:@Component),结合使用。

能够让 Spring 管理对象的注解,有五个。

@Autowired取出来的对象,Spring 会自动给这个对象赋值,不用担心是否还需要传参了。

至于具体原理,大家可以去搜索 Spring原理 ,会有讲到 Spring自动配置,Bean的作用域和Bean的生命周期等知识。

最后,如果这篇博客能帮到你的,请你点点赞,有写错了,写的不好的,欢迎评论指出,谢谢!

下一篇博客:SpringIoC & DI (2):IOC详解(五个类注解)

相关推荐
tb_first2 小时前
万字超详细苍穹外卖学习笔记5
java·数据库·spring boot·笔记·学习·spring
铁蛋AI编程实战2 小时前
ChatWiki 开源 AI 文档助手搭建教程:多格式文档接入,打造专属知识库机器人
java·人工智能·python·开源
Hx_Ma162 小时前
SpringBoot消息转换器扩展fastjson
java·spring boot·spring
Coder_preston2 小时前
Spring/Spring Boot实战:从入门到项目部署
java·spring boot·spring
山岚的运维笔记2 小时前
SQL Server笔记 -- 第16章:MERGE
java·笔记·sql·microsoft·sqlserver
Andy Dennis2 小时前
一文漫谈设计模式之创建型模式(一)
java·开发语言·设计模式
belldeep2 小时前
Java:Tomcat 9 和 mermaid.min.js 10.9 上传.csv文件实现 Markdown 中 Mermaid 图表的渲染
java·tomcat·mermaid·去除flexmark
AutumnorLiuu2 小时前
C++并发编程学习(二)—— 线程所有权和管控
java·c++·学习
Demon_Hao2 小时前
JAVA缓存的使用RedisCache、LocalCache、复合缓存
java·开发语言·缓存