在学习Spring之前,必须先了解Spring中最重要的概念之一IOC。
IOC(Inversion of Control),其中文名称为控制反转,是一种重要的设计思想。其分为两个部分控制与反转,那么这里就会有两个重要的问题:控制什么?反转什么?
控制:指控制对象的生命周期。
反转:指将对象的控制权交由Spring容器处理。
现在理解起来可能十分困难,等文章最后我们再来详细聊聊控制反转。现在通过一个例子来引出IOC。
假设现在有这么一个场景,有一个人每天下班都需要开车回家。那么怎么用编程来描述这个事件呢?
首先要有定义一辆车。这辆车名叫carA,有四个方法分别为启动、左转、右转、熄火。其结构如下:
public class CarA {
void start() { //启动
System.out.println("carA is starting!");
}
void turnLeft() { //左转
System.out.println("carA is turning left!");
}
void turnRight() { //右转
System.out.println("carA is turning right!");
}
void stop() { //熄火
System.out.println("carA is stopping!");
}
}
然后需要定义一个人。这个人叫张三,拥有一辆carA车,并且有一个回家的方法。其结构如下:
public class ZhangSan {
private CarA carA;
public ZhangSan(CarA carA) {
this.carA = carA;
}
public void goHome(){
carA.start();
carA.turnLeft();
carA.stop();
}
}
张三离家很近,只需开车启动、左转、熄火就到了。那么每天张三只需要调用goHome()方法就能回到家了。直到有一天,张三凭借着自己的积蓄,买了第二辆车carB。那么同样我们需要定义这么一辆车carB,其结构和carA完全相同,并且需要把ZhangSan类中的所有和车有关的都换成carB。
这时我们就发现问题了,如果某天张三拥有十辆车了,一天一辆轮着开,那么我们每天都需要频繁的修改ZhangSan类拥有的车及goHome方法,这是十分不合理的。
这时我们需要明白,其实ZhangSan只需要回家的操作,他本身并不关注开的是什么车。换句话说,他家的保镖只需要在他公司下面停一辆车供张三下班后开回家,张三本身不关心开什么车回家。那么我们就可以进行重构,其结构如下:
public abstract class Car {
abstract void start();
abstract void turnLeft();
abstract void turnRight();
abstract void stop();
}
我们先抽象出这个车,只要张三买一辆车就继承这个抽象车。
public class ZhangSan {
private Car car;
public ZhangSan(Car car) {
this.car = car;
}
public void goHome(){
car.start();
car.turnLeft();
car.stop();
}
}
接着,ZhangSan类只需要把车改为抽象车,这样就可以实现每天开不同的车(多态)。此时我们可以在主函数中这样测试。
public static void main(String[] args) {
Car car = new CarA(); //今天开A车
ZhangSan zhangSan = new ZhangSan(car);
zhangSan.goHome();
}
这样就可以解决上述的问题,张三今天想开什么车,就new一个车,然后回家,省去了在ZhangSan类中进行修改。但还有问题,张三每天想开不同的车就得new不同的车,他嫌太麻烦。他想可不可以每天公司下面停着自己的所有车,下班想开哪一辆开哪一辆。
这时引出了本文的主题IOC。我们可以把对象事先存放在Spring容器中(先把所有车停到公司下面),然后当我们需要某个对象时直接从Spring容器中取(下班后取一辆车)。这样就不用每次频繁的修改源代码new不同的对象了。此时再回过头来谈谈什么是IOC(控制反转)。
控制反转即将对象的控制权交由Spring容器处理。在传统的开发模式下,我们往往会自己new对象,此时对象的控制权在程序员手中,什么时候需要用直接new一个就行。而有了IOC,程序员不需要自己手动new对象,Spring会把所有对象创建好放到了一个容器中,程序员想用直接拿就好了。由此可以看出Spring的核心思想控制反转,对象的控制权由程序员转变到了Spring,程序员再也不用关心创建对象的过程,只需要关注对象的使用就行。
同样,也可以抽象出Person类,实现不同的人开不同的车回家。只需将对象都交由Spring容器去处理。
那么Spring框架是如何实现IOC的呢,将在下一小节详细描述。