目录
- Spring是什么?
- 什么是容器?
- 什么是IoC?
- 传统开发
- ioc 开发(控制反转式程序开发)
- DI(依赖注入)
Spring是什么?
Spring
指的是Spring Framework
(Spring框架),它是一个开源框架,有着活跃而庞大的社区,这就是它之所以能长久不衰的原因。Spring支持广泛的应用场景,它可以让Java企业极的应用程序开发起来更简单。
简单概况Spring:Spring
是包含了众多工具方法的IoC容器。
什么是容器?
容器是用来容纳某种物品的(基本)装置。
例如:
List/Map --> 数据存储容器
Tomcat --> Web容器
什么是IoC?
Spring
也是一个容器,Spring
是什么容器?Spring
是一个IoC
容器。
IoC = Inversion of Control
翻译成中文是“控制反转”的意思,也就是说Spring
是一个“控制反转”的容器。控制反转(对象的生命周期)
传统开发
不好理解是吧!举个示例:
假如,我们现在构建一辆“车”的程序,我们的实现思路是这样的:
构建一辆车,然后车需要依赖车身,而车身需要依赖地盘,而地盘需要依赖轮胎,代码实现如下:
汽车类
package old;
public class Car {
private Framework framework;
public Car() {
framework = new Framework();
}
public void init() {
System.out.println("执行了 car init 方法");
// 依赖车身
framework.init();
}
}
车身类
package old;
public class Framework {
private Bottom bottom;
public Framework() {
bottom = new Bottom();
}
public void init() {
System.out.println("执行了 framework init 方法");
// 依赖底盘
bottom.init();
}
}
底盘类
package old;
public class Bottom {
private Tire tire;
public Bottom() {
tire = new Tire();
}
public void init() {
System.out.println("执行了 bottom init 方法");
// 依赖轮胎
tire.init();
}
}
轮胎类
package old;
public class Tire {
private int size = 20;
public void init() {
System.out.printf("执行了轮胎初始化方法:size = " + this.size);
}
}
测试类
package old;
public class App {
public static void main(String[] args) {
Car car = new Car();
car.init();
}
}
上面的程序中,轮胎的尺寸是固定的,然而随着对车的需求量越来越大,个性化需求也会越来越多,这时候我们就需要加工多种尺寸的轮胎,那这个时候就要对上面的程序进行修改了,修改的代码如下所示:
汽车类
package old;
public class Car {
private Framework framework;
public Car(int size) {
framework = new Framework(size);
}
public void init() {
System.out.println("执行了 car init 方法");
// 依赖车身
framework.init();
}
}
车身类
package old;
public class Framework {
private Bottom bottom;
public Framework(int size) {
bottom = new Bottom(size);
}
public void init() {
System.out.println("执行了 framework init 方法");
// 依赖底盘
bottom.init();
}
}
底盘类
package old;
public class Bottom {
private Tire tire;
public Bottom(int size) {
tire = new Tire(size);
}
public void init() {
System.out.println("执行了 bottom init 方法");
// 依赖轮胎
tire.init();
}
}
轮胎类
package old;
public class Tire {
private int size = 20;
public Tire(int size) {
this.size = size;
}
public void init() {
System.out.printf("执行了轮胎初始化方法:size = " + this.size);
}
}
测试类
package old;
public class App {
public static void main(String[] args) {
Car car = new Car(15);
car.init();
}
}
看了上面的代码,大家会不会想:当最底层代码改动之后,整个调⽤链上的所有代码都需要修
改。
ioc 开发(控制反转式程序开发)
如何去解决这个问题呢?
我们可以尝试不在每个类中⾃⼰创建下级类,如果⾃⼰创建下级类就会出现当下级类发⽣改变操作,⾃⼰也要跟着修改。
此时,我们只需要将原来由⾃⼰创建的下级类,改为传递的⽅式(也就是注⼊的⽅式),因为我们不需要在当前类中创建下级类了,所以下级类即使发⽣变化(创建或减少参数),当前类本身也⽆需修改任何代码,这样就完成了程序的解耦。
汽车类
package ioc;
public class Car {
private Framework framework;
public Car(Framework framework) {
this.framework = framework;
}
public void init() {
System.out.println("执行了 car");
// 依赖车身
framework.init();
}
}
车身类
package ioc;
public class Framework {
private Bottom bottom;
public Framework(Bottom bottom) {
this.bottom = bottom;
}
public void init() {
System.out.println("执行了 framework");
// 依赖底盘
bottom.init();
}
}
底盘类
package ioc;
public class Bottom {
private Tire tire;
public Bottom(Tire tire) {
this.tire = tire;
}
public void init() {
System.out.println("执行 bottom");
// 依赖轮胎
tire.init();
}
}
轮胎类
package ioc;
public class Tire {
private int size = 20;
public Tire(int size) {
this.size = size;
}
public void init() {
System.out.println("轮胎:size = " + size);
}
}
测试类
package ioc;
public class App {
public static void main(String[] args) {
Tire tire = new Tire(30);
Bottom bottom = new Bottom(tire);
Framework framework = new Framework(bottom);
Car car = new Car(framework);
car.init();
}
}
通⽤程序的实现代码,类的创建顺序是反的,传统代码是 Car 控制并创建了 Framework,Framework 创建并创建了 Bottom,依次往下,⽽改进之后的控制权发⽣的反转,不再是上级对象创建并控制下级对象了,⽽是下级对象把注⼊将当前对象中,下级的控制权不再由上级类控制了,这样即使下级类发⽣任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是IoC 的实现思想。
DI(依赖注入)
在程序运行期间,动态地将某种依赖关系注入到对象之中。
Ioc是“目标”也是一种思想,而目标和思想只是一种指导原则,最终还是要有可行的落地方案,而DI就属于具体的实现