1. Spring 是什么?

我们通常讲的Spring指的是Spring Framework(Spring框架),它是一个开源的框架,有着活跃而庞大的社区,这也是它之所谓经久不衰的原因。官方的解读是:Spring官网

在这里插入图片描述

翻译过来就是:Spring使Java编程对每个人来说更快、更容易、更安全。Spring对速度、简单性和生产力的关注使它成为全球最受欢迎Java框架。

用一句话概括Spring:包含了众多工具方法的IoC容器,也就是说Spring最核心的功能就是容器管理 。 这句话大抵有两个方面需要解读,一是IoC,二是容器。

  1. 容器是什么?

    容器就是用来存储物品的一个装置,可以存,也可以取。

2. IoC是什么?

IoC = Inversion of Control (控制反转),首先IoC是一种思想,再就是说Spring是一个包含了众多工具方法的**“控制反转”的容器**。它具备两个最基础的功能:1.把对象存入容器;2.把对象取出容器。

通过一个典型且普通的Java代码案例试着理解:(此处没有使用Maven)

约定:创建一个车类,造车必须先要有车身,造车身必须先要有底盘,造底盘必须先要有轮胎。(别问为什么,天道法则,就当这是个游戏规则)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uAnJbiBk-1686298172612)(C:\Users\COFFEEWEN\AppData\Roaming\Typora\typora-user-images\image-20230609145003516.png)]

构建一个车,车需要依赖车身,车身需要依赖底盘,底盘依赖轮胎。最终代码如下:

  1. 车类
public class Car {
    public void init(){
        //构造Bottom类,因为车身类需要依赖于车身类
        Framework framework = new Framework();
        framework.init();
        System.out.println("do Car");
    }
}
  1. 车身类
public class Framework {
    public void init(){
        //构造Bottom类,因为车身类需要依赖于底盘类
        Bottom bottom = new Bottom();
        bottom.init();
        System.out.println("do Framework");
    }
}
  1. 底盘类
public class Bottom {
    public void init(){
        //构造tire类,因为车身类需要依赖于轮胎类
        Tire tire = new Tire();
        tire.init();
        System.out.println("do Bottom");
    }
}

4.轮胎类

public class Tire {
    private  int size = 17;//轮胎尺寸
    public void init(){
          System.out.println("do Tire size = "+size);

    }
}
  1. 测试类
public class Test {
    public static void main(String[] args) {
        Car car = new Car();
        car.init();
    }
}
  1. 运行结果(造车成功)

在这里插入图片描述

上述代码:当前类控制着下级类的生命周期,并且有一个缺陷就是一旦最底层的代码改动后,整个调用链都需要跟着改动,比如在Tire类的init()方法增加一个形参,那么整个调用链都需要增加一个形参,这样每个类的耦合性太高,我们可以试着将原来当前类自己创建下级类的方法,改为传递的方式(注入的方式),因此最底层类发生变化,当前类也不需要修改代码.这样就完成了解耦。(好的代码要高内聚,低耦合)
在这里插入图片描述

  1. 车类
public class Car {
    Framework framework;
    public Car(Framework framework){
        this.framework = framework;
    }
    public void init(){
        System.out.println("do Car");
        framework.init();
    }
}
  1. 车身类
public class Framework {
    Bottom bottom;
    public Framework(Bottom bottom){
        this.bottom = bottom;
    }
    public void init(){
        System.out.println("do Framework");
        bottom.init();
    }
}
  1. 底盘类
public class Bottom {
    Tire tire ;
    public Bottom(Tire tire){
        this.tire = tire;
    }
    public void init(){
        System.out.println("do Bottom");
        tire.init();
    }
}
  1. 轮胎类
public class Tire {
    private int size = 17;
    //此时增加 size参数,就不需要改动上层代码
    public Tire(int size){
        this.size = size;
    }
    public void init(){
        System.out.println("do Tire size = "+size);
    }
}
  1. 测试类
public class Test {
    public static void main(String[] args) {
    //此时修改 size参数,就不需要改动上层代码
        Tire tire = new Tire(20);
        Bottom bottom = new Bottom(tire);
        Framework framework = new Framework(bottom);
        Car car = new Car(framework);
        car.init();
    }
}

这就是控制反转式的开发,通过以上调整,最底层代码改动,整个调用链不需要做任何改变,这样就完成了代码之间的解耦,从而更加灵活,通用了。下层类的生命也就交给了第三方实现(spring IoC),不再是当前类控制着下层类的生命周期。因此可以得出IoC核心功能之一是解耦

我们发现一个很明显的现象:传统的代码和改进后的代码,创建类的顺序是相反的;传统代码Car类创建Framework对象,Framwork类创建Bottom对象依次往下。改进后“控制权”便发生了反转,不再是上级类控制下级对象了,而是把下级对象注入到当前类中,而对象的创建和销毁则交给了第三方实现,把对象存入第三方,用时就去取对象。这就是典型的**“控制反转”,也就是IoC的实现思想再回头思考Spring是什么?它是一个IoC容器,意思是把对象的创建和销毁的权利交给了Spring管理,它本身具备了存储对象和获取对象的能力.**

2.DI概念说明

说到IoC就逃不过DI,首先DI是Dependency Injection的缩写,翻译过来就是"依赖注入"的意思。所谓“依赖注入”的意思是:在框架运行时,动态的把某个对象动态的拿到(注入)当前类中。官方点的话,当某个java 实例需要另一个java实例时,创建被调用者的工作不是由调用者实现,而是由spring容器来完成,然后注入调用者,因此称为依赖注入。(此处Spring容器就可以理解为第三方)

“IoC”是一种思想,而“DI”则是思想的具体实现。

就是"依赖注入"的意思。所谓“依赖注入”的意思是:在框架运行时,动态的把某个对象动态的拿到(注入)当前类中。官方点的话,当某个java 实例需要另一个java实例时,创建和被调用的工作不是由调用者实现,而是由spring容器来完成,然后注入调用者,因此称为依赖注入。(此处Spring容器就可以理解为第三方)

上述代码在测试类中创建每个对象(把控制权交给了测试类),因此Car类需要用Framework对象时,只需要动态的把Framework对象注入到Car类就可以了。
DI和IoC是从不同角度做同一件事的(解耦),IoC是把控制权交给spring,用还是要用的;DI是把依赖的对象交给别人,需要用时动态的去取。两者都有共同的特点:更简单,更高效,更解耦

“IoC”是一种思想,而“DI”则是思想的具体实现。
比如我今天打算去欢乐谷玩,这是一种思想,乘坐地铁或是出租车到达欢乐谷,这是具体的实现。

IoC和DI的面试题

IoC和DI的是什么:IoC Inversion of Control 控制反转,DI dependency Injection 依赖注入。
IoC和DI的区别:IoC和DI本质上是从不同的方面做同一件事,IoC是一种思想,DI是一种具体实现,把依赖进行注入,当程序运行时动态的把某个依赖拿到当前的类中。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐