Spring 是什么?IoC 和 DI的区别
**用一句话概括Spring:包含了众多工具方法的IoC容器,也就是说Spring最核心的功能就是容器管理。**这句话大抵有两个方面需要解读,一是IoC,二是容器。
1. Spring 是什么?
我们通常讲的Spring指的是Spring Framework(Spring框架),它是一个开源的框架,有着活跃而庞大的社区,这也是它之所谓经久不衰的原因。官方的解读是:Spring官网
翻译过来就是:Spring使Java编程对每个人来说更快、更容易、更安全。Spring对速度、简单性和生产力的关注使它成为全球最受欢迎Java框架。
用一句话概括Spring:包含了众多工具方法的IoC容器,也就是说Spring最核心的功能就是容器管理 。 这句话大抵有两个方面需要解读,一是IoC,二是容器。
-
容器是什么?
容器就是用来存储物品的一个装置,可以存,也可以取。
2. IoC是什么?
IoC = Inversion of Control (控制反转),首先IoC是一种思想,再就是说Spring是一个包含了众多工具方法的**“控制反转”的容器**。它具备两个最基础的功能:1.把对象存入容器;2.把对象取出容器。
通过一个典型且普通的Java代码案例试着理解:(此处没有使用Maven)
约定:创建一个车类,造车必须先要有车身,造车身必须先要有底盘,造底盘必须先要有轮胎。(别问为什么,天道法则,就当这是个游戏规则)
构建一个车,车需要依赖车身,车身需要依赖底盘,底盘依赖轮胎。最终代码如下:
- 车类
public class Car {
public void init(){
//构造Bottom类,因为车身类需要依赖于车身类
Framework framework = new Framework();
framework.init();
System.out.println("do Car");
}
}
- 车身类
public class Framework {
public void init(){
//构造Bottom类,因为车身类需要依赖于底盘类
Bottom bottom = new Bottom();
bottom.init();
System.out.println("do Framework");
}
}
- 底盘类
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);
}
}
- 测试类
public class Test {
public static void main(String[] args) {
Car car = new Car();
car.init();
}
}
- 运行结果(造车成功)
上述代码:当前类控制着下级类的生命周期,并且有一个缺陷就是一旦最底层的代码改动后,整个调用链都需要跟着改动,比如在Tire类的init()方法增加一个形参,那么整个调用链都需要增加一个形参,这样每个类的耦合性太高,我们可以试着将原来当前类自己创建下级类的方法,改为传递的方式(注入的方式),因此最底层类发生变化,当前类也不需要修改代码.这样就完成了解耦。(好的代码要高内聚,低耦合)
- 车类
public class Car {
Framework framework;
public Car(Framework framework){
this.framework = framework;
}
public void init(){
System.out.println("do Car");
framework.init();
}
}
- 车身类
public class Framework {
Bottom bottom;
public Framework(Bottom bottom){
this.bottom = bottom;
}
public void init(){
System.out.println("do Framework");
bottom.init();
}
}
- 底盘类
public class Bottom {
Tire tire ;
public Bottom(Tire tire){
this.tire = tire;
}
public void init(){
System.out.println("do Bottom");
tire.init();
}
}
- 轮胎类
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);
}
}
- 测试类
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是一种具体实现,把依赖进行注入,当程序运行时动态的把某个依赖拿到当前的类中。
更多推荐
所有评论(0)