spring ioc最关键的作用在于解耦,它可以解除对象之间的耦合,让对象和对象之间完全没有联系,这样我们在完成或修改一个对象时不需要考虑其它对象。
什么是ioc
ioc全称是【Inversion of Control】控制反转,按照字面意思理解,将控制反转过来,这里的控制指的是什么,为什么要进行反转,ioc可以解决什么问题?要回答这些问题,我们需要先了解一下ioc为什么会产生
为什么要有ioc
java是一门面向对象的语言,我们的应用程序通过一个个对象之间的相互关联和作用来完成功能,在网上看到一个特别形象的比喻,这里借用一下:
![](https://i-blog.csdnimg.cn/blog_migrate/cbd84adc985bbc1d845571c110c938e3.jpeg)
![](https://i-blog.csdnimg.cn/blog_migrate/7019e330d388f1f20412440614ca8bb0.jpeg)
这里的每一个齿轮代表一个对象,对象之间彼此紧密咬合形成一个系统,这样的系统对象之间的耦合度非常高,所谓的耦合度就是关系的紧密程度,高耦合度带来的问题显而易见,只要有一个齿轮发生故障,其它齿轮也无法工作,进而整个系统都无法正常工作,这种牵一发而动全身情况如何才能改善呢?看下图:
![](https://i-blog.csdnimg.cn/blog_migrate/3012fff1e2293a54e2c2799bd6cd23f1.jpeg)
![](https://i-blog.csdnimg.cn/blog_migrate/03185c5eb5774f5380b725124b1c56cd.jpeg)
中间这个齿轮好比一个粘合剂将其它几个齿轮粘合起来,所有的齿轮都交由中间这个齿轮管理,试着把中间这个齿轮拿掉我们可以看到这三个齿轮之间彼此毫无关系,即使一个齿轮出了故障,也不会影响到其它齿轮,中间这个齿轮就好比ioc容器,其它齿轮就是对象,可以看出引入了ioc容器,对象之间的耦合度降低了。当我们修改一个对象的时候不需要去考虑其它对象,因为它不会对其它对象造成影响。
ioc的原理
这里说到的ioc容器到底是个什么东东,又是什么让它具有如此神奇的力量?
先来看一下没有ioc容器的时候,对象A依赖对象B,A在运行到某一时刻的时候会去创建B的对象,在这里A具有主动权,它控制了对象B的创建。
引入ioc以后对象A和对象B之间没有了直接联系,当A运行的时候由ioc容器创建B对象在适当的时候注入到A中,在这里,控制权由A对象转移到了ioc容器。这也就是控制反转名称的由来。
看一个例子:
public class UserServiceImpl {
private UserDao userDaoImpl
public List<User> getAllUser(){
userDaoImpl = new UserDaoImpl();
return userDaoImpl.getAllUser();
}
}
这里UserServiceImpl依赖UserDaoImpl,需要在UserServiceImpl中创建UserDaoImpl对象,对象之间的耦合性很高,如何解耦呢?
我们可以通过反射来解耦,反射可以根据类的全限定名在程序运行时创建对象,可以这样做,将类的全限定名配置在xml文件中,在程序运行时通过反射读取该类的全限定名,动态的创建对象,赋值给userDao接口userDaoImpl.这样做后UserServiceImpl和UserDaoImpl之间没有了直接的关系,当我们需要替换UserDaoImpl对象的时候只需要在配置文件中去修改类的全限定名就可以了,非常的灵活方便,ioc容器的实现就是这个原理。
Ioc容器可以自动的帮我们完成以上一系列操作,我们需要做的就是通过配置文件告诉ioc需要创建哪个类以及类和类之间的关系。
控制反转和依赖注入
在这里需要提到一个概念依赖注入,很多初学者搞不清楚控制反转和依赖注入之间的关系,其实他们是对同一事物的不同角度的描述。
控制反转是一种设计思想而依赖注入是这种思想的具体实现
具体说控制反转就是将创建userDaoImpl对象的控制权反转过来由UserServiceImpl交给了ioc容器,强调的是一种能力和思想,ioc容器具有了控制权。
依赖注入就是ioc容器将UserServiceImpl所依赖的对象userDaoImpl,注入给UserServiceImpl,强调的是一个过程和实现
具体spring ioc是如何帮我们完成的,他的底层有哪些重要的类,我会单独再写一篇文章。
转载自知乎: 夏昊(高级Java工程师讲师)