大家好我是小帅,今天的目标是:
- 了解Spring,Spring MVC, Spring Boot 之间的联系及区别
- 掌握IoC&DI的概念以及写法
文章目录
1. IoC & DI ⼊⻔
1.1 Spring 是什么?
通过前⾯的学习, 我们知道了Spring是⼀个开源框架, 他让我们的开发更加简单. 他⽀持⼴泛的应⽤场景, 有着活跃⽽庞⼤的社区, 这也是Spring能够⻓久不衰的原因.
但是这个概念相对来说, 还是⽐较抽象.我们⽤⼀句更具体的话来概括Spring, 那就是: Spring 是包含了众多⼯具⽅法的 IoC 容器.
1.2 什么是容器?
容器是⽤来容纳某种物品的(基本)装置.
List/Map -> 数据存储容器
Tomcat -> Web 容器.
1.3 什么是 IoC?
其实IoC我们在前⾯已经使⽤了, 我们在前⾯讲到, 在类上⾯添加@RestController 和@Controller 注解, 就是把这个对象交给Spring管理, Spring 框架启动时就会加载该类. 把对象交给Spring管理, 就是IoC思想.
IoC: Inversion of Control (控制反转), 也就是说 Spring 是⼀个"控制反转"的容器.
什么是控制反转呢? 也就是控制权反转. 什么的控制权发⽣了反转? 获得依赖对象的过程被反转了,也就是说, 当需要某个对象时, 传统开发模式中需要⾃⼰通过 new 创建对象, 现在不需要再进⾏创建, 把创建对象的任务交给容器, 程序中只需要依赖注⼊ (Dependency Injection,DI)就可以了.这个容器称为:IoC容器. Spring是⼀个IoC容器, 所以有时Spring 也称为Spring 容器
2. IoC程序开发
基于以上思路,我们把调⽤汽⻋的程序⽰例改造⼀下,把创建⼦类的⽅式,改为注⼊传递的⽅式.
具体实现代码如下:
package com.cdm.book;
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();
}
static class Car {
private Framework framework;
public Car(Framework framework) {
this.framework = framework;
System.out.println("Car init....");
}
public void run() {
System.out.println("Car run...");
}
}
static class Framework {
private Bottom bottom;
public Framework(Bottom bottom) {
this.bottom = bottom;
System.out.println("Framework init...");
}
}
static class Bottom {
private Tire tire;
public Bottom(Tire tire) {
this.tire = tire;
System.out.println("Bottom init...");
}
}
static class Tire {
private int size;
public Tire(int size) {
this.size = size;
System.out.println("轮胎尺⼨:" + size);
}
}
}
2.1 IoC 优势
在传统的代码中对象创建顺序是:Car -> Framework -> Bottom -> Tire
改进之后解耦的代码的对象创建顺序是:Tire -> Bottom -> Framework -> Car
我们发现了⼀个规律,通⽤程序的实现代码,类的创建顺序是反的,传统代码是 Car 控制并创建了Framework,Framework 创建并创建了 Bottom,依次往下,⽽改进之后的控制权发⽣的反转,不再是使⽤⽅对象创建并控制依赖对象了,⽽是把依赖对象注⼊将当前对象中,依赖对象的控制权不再由当前类控制了.
这样的话, 即使依赖类发⽣任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是 IoC 的实现思想。
那什么是控制反转容器呢?
IoC容器具备以下优点:
- 资源集中管理: IoC容器会帮我们管理⼀些资源(对象等), 我们需要使⽤时, 只需要从IoC容器中去取就可以了
- 我们在创建实例的时候不需要了解其中的细节, 降低了使⽤资源双⽅的依赖程度, 也就是耦合度.
3. IoC & DI 使⽤
依然是先使⽤, 再学习
既然 Spring 是⼀个 IoC(控制反转)容器,作为容器, 那么它就具备两个最基础的功能:取和存
那么我们怎么来存呢?
我们来搞搞事。
我们来看看代码:
存
package com.cdm.springiocdi20241214.model;
import lombok.Data;
import org.springframework.stereotype.Component;
@Data
@Component
public class Student {
private String name;
private int age;
private int score;
public Student() {
this.run();
}
public void run() {
this.name = "zhangsan";
this.age = 18;
this.score = 90;
}
}
解释:
取
代码:
@RestController
@RequestMapping("/test")
@Component
public class StudentController {
//取出Spring容器里面的Student对象赋值给下面成员变量
@Autowired
private Student student;
//返回字符串为json类型
@RequestMapping(value = "/getStudent", produces = "application/json")
public String getStudent() {
return student.toString();
}
}
4. IoC 详解
通过上⾯的案例, 我们已经知道了Spring IoC 和DI的基本操作, 接下来我们来系统的学习Spring IoC和DI的操作.
4.1 Bean的存储
在之前的⼊⻔案例中,要把某个对象交给IOC容器管理,需要在类上添加⼀个注解: @Component⽽Spring框架为了更好的服务web应⽤程序, 提供了更丰富的注解.
共有两类注解类型可以实现:
- 类注解:@Controller、@Service、@Repository、@Component、@Configuration.
- ⽅法注解:@Bean.
4.1.1 @Controller(控制器存储)
使⽤ @Controller 存储 bean 的代码如下所⽰:
@Controller // 将对象存储到 Spring 中
public class UserController {