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 这个词语,能够表示这些意思意思:
- Spring家族
- 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容器中的某个对象给 变量,会出现这样的错误:


总结:
我们学了两个注解:
- @Component:表示将这个类自动创建对象,这个对象,放到 SpringIoC容器中,交给 Spring 管理。(存放对象到容器中)
- @Autowired:表示从 SpringIoC容器中,获取某一个对象,并赋值给一个 引用变量。(从容器中取对象)
@Autowired 必须要和 任意一个能够让 Spring管理对象的注解(例如:@Component),结合使用。
能够让 Spring 管理对象的注解,有五个。
@Autowired取出来的对象,Spring 会自动给这个对象赋值,不用担心是否还需要传参了。

至于具体原理,大家可以去搜索 Spring原理 ,会有讲到 Spring自动配置,Bean的作用域和Bean的生命周期等知识。
最后,如果这篇博客能帮到你的,请你点点赞,有写错了,写的不好的,欢迎评论指出,谢谢!