Spring IoC(1)
1.IoC
什么是IoC呢?IoC:控制反转,传统开发中当需要某一个对象时,需要自己new创建对象,如果应用IoC思想,就不需要自己手动创建对象了,把创建对象的任务交给容器,程序中只需要依赖注入就可以.这个容器称为:IoC容器.Spring是一个包含了众多工具方法的IoC容器,IoC是Spring的核心思想.前面用到的@Controller和@RestController注解,就是把这个类交给Spring管理,Spring框架启动时就会加载该类,把这个对象交给Spring管理,就是IoC思想.
一个应用IoC思想的例子
如果需要制造一辆车,传统的开发程序是:先设计轮子,然后根据轮子的大小设计底盘,接着根据底盘设计车身,最后根据车身设计整个汽车.这里就有一个依赖关系:汽车依赖车身,车身依赖底盘,地盘依赖轮子.具体的代码如下:
import javax.xml.transform.Source;
import java.net.SocketTimeoutException;public class NewCar1 {public static void main(String[] args) {Car car=new Car();car.run();}
// 汽车类static class Car{private Framework framework;public Car(){this.framework=new Framework();System.out.println("Car init...");}public void run(){System.out.println("Car run...");}}
// 车身类static class Framework{private Bottom bottom;public Framework(){this.bottom=new Bottom();System.out.println("framework init...");}}// 地盘类static class Bottom{private Tire tire;public Bottom(){this.tire=new Tire();System.out.println("bottom init...");}}
// 轮子类static class Tire{private int size;public Tire(){this.size=17;System.out.println("轮胎尺寸: "+size);}}
}
这样写看不出来有什么问题,但是可以发现,如果需要加工多种尺寸的轮胎,代码需要改动的地方较多,代码的可维护性较低.完整修改后的代码如下:
import javax.xml.transform.Source;
import java.net.SocketTimeoutException;public class NewCar1 {public static void main(String[] args) {Car car=new Car(18);car.run();}
// 汽车类static class Car{private Framework framework;public Car(int size){this.framework=new Framework(size);System.out.println("Car init...");}public void run(){System.out.println("Car run...");}}
// 车身类static class Framework{private Bottom bottom;public Framework(int size){this.bottom=new Bottom(size);System.out.println("framework init...");}}// 地盘类static class Bottom{private Tire tire;public Bottom(int size){this.tire=new Tire(size);System.out.println("bottom init...");}}
// 轮子类static class Tire{private int size;public Tire(int size){this.size=size;System.out.println("轮胎尺寸: "+size);}}
}
这个简单的代码存在的问题是,当tire的代码改动之后,所有调用链上的代码都需要改变,代码的耦合度非常高.
修改方案:上面的程序出现问题的原因是由于,根据轮子设计底盘,根据底盘设计车身,因此只要轮子发生变化,底盘,车身等结构都需要进行修改.这里应用控制反转的思想,把依赖关系倒置即可,使轮子依赖底盘,底盘依赖车身,车身依赖汽车.如何做呢?就是把原来由自己创建类的方式改为传递的方式即可.这样下级类发生变化时,当前的类本身也无需修改任何代码,就完成了程序的解耦.
import java.net.SocketTimeoutException;public class IOCCar {public static void main(String[] args) {Tire tire=new Tire(20);Bottom bottom=new Bottom(tire);FrameWork frameWork=new FrameWork(bottom);Car car=new Car(frameWork);car.run();}static class Car{private FrameWork frameWork;public Car(FrameWork framework){this.frameWork=framework;System.out.println("cat init...");}public void run(){System.out.println("Car run...");}}static class FrameWork{private Bottom bottom;public FrameWork(Bottom bottom){this.bottom=bottom;System.out.println("FrameWork init...");}}static class Bottom{private Tire tire;public Bottom(Tire tire){this.tire=tire;System.out.println("Bottom init...");}}static class Tire{private int size;public Tire(int size){this.size=size;System.out.println("轮胎尺寸: "+size);}}
}
可以看出,经过上述的调整,通过注入的方式完成了代码的解耦.对比这两种代码,可以发现,传统代码是Cai控制并创建了Framework,Framework 控制并创建Bottom,依次往下.而改进之后的控制权发生反转,不再是使用方对象创建并控制对象了,而是把依赖对象注入当前对象中,依赖对象的控制权不再由当前类控制了.这样一来,即使依赖类发生变化,当前类都是不受影响的,这就是典型的控制反转思想,即IoC思想的实现.前面说过Springs是一个集合了多种工具的IoC容器.什么是IoC容器呢?
这些代码完成的工作就是IoC容器完成的工作.IoC容器具有以下的优点:
1.资源集中管理:IoC容器会帮我们管理一些资源等,我们需要使用时,只需要从Ioc容器中去取就可以了.
2.在创建实例的时候不需要了解双方的细节,降低了资源双方的耦合度.Spring就是一种Ioc容器,帮助我们来做了这些资源管理.
2.DI介绍
DI:Dependency Injection(依赖注入),容器在运行期间,动态的为应用程序提供运行时所依赖的资源,称之为依赖注入.程序运行时需要某个资源,此时容器就为其提供这个资源.前面应用IoC思想的代码中,是通过构造函数的方式,把依赖对象注入的需要使用的对象中的.IOC是一种思想,DI可以认为是这种思想的实现.