什么是IoC?
IoC,全称Inversion of Control,即控制反转。IoC并不是某一具体的技术,而是一种设计思想,Spring IoC框架/容器就是IoC这一思想的具体实现。
IoC的核心思想在于,资源不由使用资源的双方管理,交由不使用资源的第三方管理。在通常情况下,当我们需要使用或依赖某一个类或服务,我们通常会使用new关键字等方法直接地主动地创建对象。而在IoC的思想下,创建对象这部分工作被委托给了IoC容器,即将此工作的控制权交由IoC容器,控制反转。图示如下:
以Spring IoC容器为例,它负责创建对象、自动装配对象、配置对象,并管理这些对象(bean)的生命周期。
引用《Spring揭秘》中的一句话概括IoC:“IoC是一种可以帮助我们解耦各业务对象间依赖关系的对象绑定方式!”
IoC的两种实现方式
IoC这一思想的具体实现由两种方式,分别为:依赖注入(DI,Dependency Injection)、依赖查找(DL,Dependency Lookup)。
什么是依赖
依赖,即Dependency,是非常常见的概念,简单举例说明,假设现有两个类A和B,如果在A类中引用了B类,即有B类型字段在A类中,就可以说A类依赖于B类,B类是A类的依赖。
回到正题,依赖注入和依赖查找二者最重要的区别在于依赖绑定的过程是主动的还是被动的:
依赖注入
此实现方法指某对象的依赖通过注入的方式进行创建,由容器动态将依赖关系中的目标对象实例注入到各组件中,对象实例的创建配置等工作均由容器完成实现。
依赖注入对代码的侵入性较小,即硬编码部分不多,可以很好的提升代码的重用率,更加灵活易扩展,实现本身不需要依赖过多容器的API,耦合度较小。
依赖注入有三种方式,分别是接口注入、构造方法注入和setter注入,其中接口注入由于其代码侵入性过高,已鲜有使用。在Spring中,诸如@Autowired和@Resource等注解就是依赖注入的体现。
依赖查找
依赖查找是一种十分传统的IoC实现方式,即容器中的对象通过容器的API来查找该对象所依赖的资源,此种方式相较依赖注入,更多的依赖了容器的API,即用户需要自己手动地主动地使用容器的API去查找资源组装对象。
依赖查找也有两种方式,分别是依赖拖拽和上下文依赖查找。
阅读过依赖注入和依赖查找的简述,想必读者都能分清哪种实现方式更能体现IoC的思想,更不背离IoC思想的初衷,答案当然是依赖注入,依赖查找这种方式因侵入性高,且需要开发人员主动调用容器API,在实践中鲜有人使用,可以大概认定为已被弃用。
而依赖注入因其是IoC框架的核心实现,且十分符合IoC的思想,也有人认为控制反转和依赖注入是同一种概念,此处见仁见智。
IoC与依赖查找及依赖注入关系图如下:
使用IoC的优缺点
优点
- 解耦。由于引入了第三方资源管理者,降低了资源使用双方的耦合度。
- 资源集中管理。使得资源可配置易管理。
缺点
- 创建对象的过程没有使用new关键字创建直观,相较复杂。
- Java中IoC使用反射创建对象,效率没有直接创建高。
- 使用非基于注解的IoC,即基于配置文件的方式需要手动配置。