什么是IOC?
IOC(Inversion of Control)翻译过来叫控制反转或反转控制。当我们需要创建一个对象,原始方式是new一个对象。比如现在有两个类,我在一个类中想用另一个类的方法,那么就将一个类的引用传过去进行使用,或者在一个类中创建另一个类的对象进行使用。
而现在这个过程可以通过IOC进行实现,它实现的好处是什么呢?可以帮我们实现解耦的操作。简单来说,控制反转就是把对象创建和对象之间的调用过程,交给Spring进行管理。
在耦合度较高的系统中,各个对象之间互相调用来完成功能。
图一
现在借助于"第三方"实现具有依赖关系的对象之间的解耦。这个"第三方"就是IOC容器。使得A、B、C、D这4个对象没有了耦合关系,齿轮之间的传动全部依靠“第三方”了,全部对象的控制权全部上缴给“第三方”IOC容器,所以,IOC容器成了整个系统的关键核心,它起到了一种类似“粘合剂”的作用,把系统中的所有对象粘合在一起发挥作用,如果没有这个“粘合剂”,对象与对象之间会彼此失去联系,这就是有人把IOC容器比喻成“粘合剂”的由来。
图二
此时如果去掉IOC容器以后,发现对象之间已经解耦了。
图三
软件系统在没有引入IOC容器之前,如图1所示,对象A依赖于对象B,那么对象A在初始化或者运行到某一点的时候,自己必须主动去创建对象B或者使用已经创建的对象B。无论是创建还是使用对象B,控制权都在程序员自己手上。
软件系统在引入IOC容器之后,这种情形就完全改变了,如图2所示,由于IOC容器的加入,对象A与对象B之间失去了直接联系,所以,当对象A运行到需要对象B的时候,IOC容器会主动创建一个对象B注入到对象A需要的地方。
通过前后的对比,我们不难看出来:对象A获得依赖对象B的过程,由主动行为变为了被动行为,控制权颠倒过来了,这就是“控制反转”这个名称的由来。
IOC底层原理
OC底层原理主要用到三个技术。
(1)xml解析、工厂模式、反射。
工厂模式的出现就是为了解耦合。工厂模式可以降低两个类之间的耦合,但是无法将耦合降到最低限度。所以还需要使用到xml解析技术和反射。反射就是通过得到字节码文件可以操作你类的全部内容。
使用xml解析获取全类名,再使用反射通过类名来创建对象。这样当类名发生改变,只需要在配置文件中修改即可,而不需要在service层或者其他地方修改代码。
IOC的过程就是主要用到xml解析,反射再加上工厂然后实现出IOC过程,目的就是解耦合。让耦合降低到最低限度。这就是底层原理的基本介绍。所以我们用Spring框架其实就是为了简化代码,让耦合度降低。而IOC就是用来解决这个问题,把你的对象创建,还有对象之间调用的过程都交给Spring来处理。
IOC接口
IOC思想基于IOC容器完成,IOC容器底层就是对象工厂,Spring里边对IOC 容器的实现给我们提供了两种方式。
(1)BeanFactory:IOC容器里面最基本的一种实现方式。是Spring中内置的一种方式,是它本身自己用的,这个接口一般开发中不去使用,因为它是Spring里面自带的一种东西。是Spring内部的使用接口,不提供给开发人员进行使用。
BeanFactory在加载配置文件的时候不会去创建对象,而是在获取对象(使用)的时候才去创建。也就是当new ClassPath…()的时候不会去创建对象。(有点像懒汉式)
(2)ApplicationContext:BeanFactory接口的子接口,提供了更多更强大的功能,这个接口一般是面向开发人员使用的,开发中几乎都用这个接口。
ApplicationContext在加载配置文件时候就会把在配置文件对象进行创建,也就是当new ClassPath…()的时候就会创建对象。只要你给bean配置了id,class,不管你创建了多少bean,它都能完成创建。(有点像饿汉式)
看起来BeanFactory更加合适,什么时候用什么时候创建。但是我们使用的是Spring框架,要结合web项目进行操作。通俗点,我们使用Tomcat进行启动,所以我们将这种耗时,耗资源的操作都在项目启动的时候处理,这样更加合适。服务器启动,在服务器启动的过程中创建这些对象,而不是说什么时候用,什么时候创建。所以一般操作中都使用ApplicationContext。把耗时耗资源的过程交给服务器,我们只管用就行。
BeanFactory和ApplicationContext的继承树。
BeanFactory:
ConfigurableApplicationContext接口是BeanFactory下面的一个子接口,这个子接口中包含一些相关的扩展功能等内容。
ApplicationContext:
FileSystemXmlApplicationContext和ClassPathXmlApplicationContext将两个接口都实现了。