public class Main {
public static void main(String[] args) {
Car car=new Car(21);
car.run();
}
}
public class Car {
private Framework framework;
public Car(Integer size){
this.framework=new Framework(size);
//有了车身,汽车才完成初始化
System.out.println("Car init...");
}
public void run(){
System.out.println("Car run...");
}
}
public class Framework {//车身
public Framework(Integer size){
this.bottom=new Bottom(size);
System.out.println("Framework init...");
}
private Bottom bottom;
}
public class Bottom {//底盘
private Tire tire;
public Bottom(Integer size){
this.tire=new Tire(size);
System.out.println("Bottom init...");
}
}
public class Tire {//轮胎
int size;
public Tire(Integer size){
this.size=size;
System.out.println("Tire init,size:"+size);
}
}
public class Main {
public static void main(String[] args) {
Tire tire=new Tire(17);
Bottom bottom=new Bottom(tire);
Framework framework=new Framework(bottom);
Car car=new Car(framework);
car.run();
}
}
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 run...");
}
}
public class Framework {//车身
public Framework(Bottom bottom){
this.bottom=bottom;
System.out.println("Framework init...");
}
private Bottom bottom;
}
public class Bottom {//底盘
private Tire tire;
public Bottom(Tire tire){
this.tire=tire;
System.out.println("Bottom init...");
}
}
public class Tire {//轮胎
int size;
String color;
public Tire(Integer size){
this.size=size;
this.color=color;
System.out.println("Tire init,size:"+size);
}
}
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();
}
}
当然不用写了,这些类我们都交给外包公司了,而 Spring 就是我们的外包公司,我们需要什么直接去 Spring 去取就好了,让 Spring 去帮我们管理这些对象~~
之前对象的控制权是这一大堆👇谁用谁来管
现在的对象控制权就在 Spring,让 Spring 帮我们做这些事情了,这就是 IoC~~
1.2.5 IoC 优势(课件内容)
在传统的代码中对象创建顺序是:Car -> Framework -> Bottom -> Tire
改进之后解耦的代码的对象创建顺序是:Tire -> Bottom -> Framework -> Car
我们发现了一个规律,通用程序的实现代码,类的创建顺序是反的,传统代码是 Car 控制并创建了 Framework,Framework 创建并创建了 Bottom,依次往下,而改进之后的控制权发生的反转,不再是使用方对象创建并控制依赖对象了,而是把依赖对象注入将当前对象中,依赖对象的控制权不再由当前类控制了.
这样的话, 即使依赖类发生任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是 IoC 的实现思想。
我们去创建对象的这个过程叫 IoC,但是对象创建完之后总要去用的,我拿来赋值给它,这个过程叫做"注入",也就是 DI
DI: Dependency Injection(依赖注入)
容器在运行期间, 动态的为应用程序提供运行时所依赖的资源,称之为依赖注入。
程序运行时需要某个资源,此时容器就为其提供这个资源.
从这点来看, 依赖注入(DI)和控制反转(IoC)是从不同的角度的描述的同一件事情,依赖注入是从应用程序的角度来描述, 就是指通过引入 IoC 容器,利用依赖关系注入的方式,实现对象之间的解耦.
上述代码中, 是通过构造函数的方式, 把依赖对象注入到需要使用的对象中的
IoC 是一种思想,也是"目标", 而思想只是一种指导原则,最终还是要有可行的落地方案,而 DI 就属于具体的实现。所以也可以说, DI 是IoC的一种实现.
比如说我今天心情比较好,吃一顿好的犒劳犒劳自己,那么"吃一顿好的"是思想和目标(是
IoC),但最后我是吃海底捞还是杨国福?这就是具体的实现,就是 DI。
2. IoC & DI 使用
对IoC和DI有了初步的了解, 我们接下来具体学习Spring 如何帮助我们实现 IoC 和 DI 的~~
闲聊:其实大家都猜出来了,就是使用"注解",一个注解搞不定我就再来一个注解,还搞不定就再来一个,反正是能搞定的,我们的 Spring 就是各种注解~~
依然是先使用, 再学习
在之前的代码中,我们知道 bookDao 这个对象是我们自己创建的,并不是 Spring 创建的
那我们如何让 Spring 帮我们创建呢??我们不知道,但我们已经在用了👇
这个 @Controller 就是告诉 Spring 帮我们创建一个对象~~我们之前学习的,你要是想调用一个类里的方法,就要先有一个对象才能调用它的方法,除非它是 static 方法(静态方法无需 new 对象即可调用),普通方法要想被调用必须要有对象,那么这个对象咋来的??我们从头到尾都没有 new UserController 👇
这个过程就是 Spring 帮我们创建了一个 UserController 这样的对象,就是通过 @Controller 这个注解创建的~~
发现 BookDao 值为 null,所以报了个空指针异常,为啥没有值??因为没有取出来,没有从 Spring 中取值,这就说明 @Autowired 是从 Spring 中拿东西,去找类型为 BookDao 这样的对象,找到之后赋值给它,当然这一切的大前提都是你要先交给 Spring 管理,这样 Spring 才能帮我们 new 对象
@Component:把 对象 交给 Spring 管理→存
@Autowired:从 Spring 中获取对象,并给属性赋值(不能加在类上)→取
答疑:没有前端请求,怎么赋值??
这都是跟后端有关,跟前端没关系的~~
实现:(课件内容,跟上面一样)
把BookDao 交给Spring管理, 由Spring来管理对象
java复制代码
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
@Component
public class BookDao {
/**
* 数据Mock 获取图书信息
*
* @return
*/
public List<BookInfo> mockData() {
List<BookInfo> books = new ArrayList<>();
for (int i = 0; i < 5; i++) {
BookInfo book = new BookInfo();
book.setId(i);
book.setBookName("书籍" + i);
book.setAuthor("作者" + i);
book.setCount(i * 5 + 3);
book.setPrice(new BigDecimal(new Random().nextInt(100)));
book.setPublish("出版社" + i);
book.setStatus(1);
books.add(book);
}
return books;
}
}
把BookService 交给Spring管理, 由Spring来管理对象
java复制代码
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class BookService {
private BookDao bookDao = new BookDao();
public List<BookInfo> getBookList() {
List<BookInfo> books = bookDao.mockData();
for (BookInfo book : books) {
if (book.getStatus() == 1) {
book.setStatusCN("可借阅");
} else {
book.setStatusCN("不可借阅");
}
}
return books;
}
}
删除创建BookDao的代码, 从Spring中获取对象
java复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class BookService {
@Autowired
private BookDao bookDao;
public List<BookInfo> getBookList() {
List<BookInfo> books = bookDao.mockData();
for (BookInfo book : books) {
if (book.getStatus() == 1) {
book.setStatusCN("可借阅");
} else {
book.setStatusCN("不可借阅");
}
}
return books;
}
}